0

マルチスレッドで基本的なプログラムを書いていますが、いくつかの問題に直面しています。

以下のプログラムでは、位置 1 でスリープすると、出力される共有データの値は常に 10 になり、位置 2 でスリープを維持すると、共有データの値は常に 0 になります。

なぜこの種の出力が来るのですか?どの場所で寝るかを決める方法。これは、ミューテックス内にスリープを配置している場合、他のスレッドがまったく実行されていないため、共有データが 0 であることを意味しますか?

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include<unistd.h>

    pthread_mutex_t lock;

    int shared_data = 0;

    void * function(void *arg)
    {
        int i ;
        for(i =0; i < 10; i++)
        {
            pthread_mutex_lock(&lock);
            shared_data++;
            pthread_mutex_unlock(&lock);
        }

        pthread_exit(NULL); 
    }


    int main()
    {
        pthread_t thread;
        void * exit_status;
        int i;

        pthread_mutex_init(&lock, NULL);

        i = pthread_create(&thread, NULL, function, NULL);

        for(i =0; i < 10; i++)
        {
            sleep(1);      //POSITION 1
            pthread_mutex_lock(&lock);
            //sleep(1);    //POSITION 2
            printf("Shared data value is %d\n", shared_data);
            pthread_mutex_unlock(&lock);
        }

        pthread_join(thread, &exit_status);

        pthread_mutex_destroy(&lock);
    }
4

2 に答える 2

2

ミューテックスをロックする前にスリープすると、他のスレッドに共有変数の値を変更するための十分な時間が与えられます。そのため、位置#1に「sleep」が付いた「10」の値が表示されます。

最初にミューテックスを取得すると、他のスレッドが値を変更する前に値を出力できるように、十分に速くロックすることができます。pthread_mutex_lock()もう一方のスレッドは、メインスレッドがスリープ状態になり、ロックが解除されるまで、通話をブロックします。その時点で、2番目のスレッドが最終的に実行され、値が変更されます。そのため、位置#2に「sleep」が付いた「0」の値が表示されます。

これは、競合状態の典型的なケースです。sleep別のマシンでは、同じコードが位置#2の呼び出しで「0」を表示しない場合があります。メインスレッドがミューテックスをロックする前に、2番目のスレッドが変数の値を1回または2回変更する機会がある可能性は十分にあります。ミューテックスは、2つのスレッドが同時に同じ変数にアクセスしないようにすることができますが、2つのスレッドがそれにアクセスする順序を制御することはできません。

于 2012-04-26T23:32:42.140 に答える
2

私はここで完全な説明をしましたが、結局それを削除しました。これは基本的な同期の問題であり、より複雑な問題に取り組む前に、それを追跡して特定できるはずです。

しかし、私はあなたにヒントを与えます:sleep()重要なのはポジション1だけです。ロックの内側にあるもう1つは、ロックの外側のコードを変更しない限り、関係ありません。

于 2012-04-26T23:33:03.467 に答える