2017-03-06 30 views
1

私のプログラムで2つのスレッドを使用しています.1つは偶数番号を印刷し、もう1つは奇数番号を順番に印刷します。以下のコードを実行すると、プログラムは0と1を出力した後にブロックされます。デッドロックのようです。
しかし、PrintEvenNos()とPrintOddNos()の両方のwhileステートメントの上にrc = pthread_mutex_lock(& mutex)を移動すると、出力は必要に応じて連続して完了します。 誰かがなぜ最初のケースで失敗し、何がデッドロックを引き起こしているのか説明できますか?pthread_mutex_lockとpthread_cond_wait /シグナルがデッドロックを引き起こす

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

pthread_t tid[2]; 
unsigned int shared_data = 0; 
pthread_mutex_t mutex; 
pthread_cond_t even,odd; 
unsigned int rc; 

void* PrintEvenNos(void*); 
void* PrintOddNos(void*); 

void main(void) 
{ 
    pthread_create(&tid[0],0,&PrintEvenNos,0); 

    pthread_create(&tid[1],0,&PrintOddNos,0); 
    sleep(3); 

    pthread_join(tid[0],NULL); 
    pthread_join(tid[1],NULL); 
} 

void* PrintEvenNos(void *ptr) 
{ 
    //rc = pthread_mutex_lock(&mutex);  /*works when I uncomment here and comment the next mutex_lock */ 
     while (shared_data <= 5) 
    {rc = pthread_mutex_lock(&mutex); 
     if(shared_data%2 == 0) 
     { printf("t1.....................................Even:%d\n",shared_data); 
     shared_data++; 
     pthread_cond_signal(&odd); 
     rc=pthread_mutex_unlock(&mutex); 
    } 
    else 
    { 
      pthread_cond_wait(&even, &mutex); 
    } 
} 
    rc=pthread_mutex_unlock(&mutex); 
} 

void* PrintOddNos(void* ptr1) 
{ 
// rc = pthread_mutex_lock(&mutex); /*works when I uncomment here and comment the next mutex_lock */ 
    while (shared_data <= 5) 
    { 
    rc = pthread_mutex_lock(&mutex); 
    if(shared_data%2 != 0) 
     { 
     printf("t2.....................................odd:%d\n",shared_data); 
      shared_data++; 
      pthread_cond_signal(&even); 
      rc=pthread_mutex_unlock(&mutex); 
     } 
     else 
      { 
       pthread_cond_wait(&odd, &mutex); 
     } 
    } 
rc=pthread_mutex_unlock(&mutex); 
} 
+1

答えに加えて、静的に、またはpthread_mutex_init()でミューテックスを初期化する必要があります。 –

+0

はい、また条件変数です。実際には、すでにグローバル変数であるため、デフォルトの初期化が既にあります。しかし、これでは一般的ではありませんが、 'PTHREAD_MUTEX_INITIALIZER'と' PTHREAD_COND_INITIALIZER'を使う必要があります。 –

答えて

0

あなたのコメントに記載されているように、ロックを解除してロックを解除してください。配置されると、プログラムに競合状態があり、したがって未定義の動作が発生します。同時アクセスを排除するために、同期なしで別のスレッドによって変更される可能性のあるデータにアクセスすることはできません。

1

待機中のスレッドがpthread_cond_waitから戻ったときにロックを再取得し、すでに所有しているミューテックスで再びpthread_mutex_lockを呼び出したため、プログラムの動作が未定義です。

ミューテックスは、コメントによって示されるように使用することを前提としています。これはまさにpthread_cond_waitのために作られたものです:それはエントリー時にロックを解除し、それを戻して再取得します。

また、ifブランチからpthread_mutex_unlockを削除してください。間違っています。一般的には、あなたのクリティカルセクションをマークする1組のlock/unlockコールだけを持つべきです。

関連する問題