条件と信号を変更するコードパスでミューテックスをロックしないと、ウェイクアップが失われる可能性があります。このプロセスのペアを検討してください。
プロセスA:
pthread_mutex_lock(&mutex);
while (condition == FALSE)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
プロセスB(不正解):
condition = TRUE;
pthread_cond_signal(&cond);
次に、命令のこの可能なインターリーブを検討します。ここで、次のようにcondition
始まりますFALSE
。
Process A Process B
pthread_mutex_lock(&mutex);
while (condition == FALSE)
condition = TRUE;
pthread_cond_signal(&cond);
pthread_cond_wait(&cond, &mutex);
condition
今でTRUE
はなく、プロセスAは、条件変数にこだわって待っている-それは、ウェイクアップ信号を逃しました。プロセスBを変更してミューテックスをロックする場合:
プロセスB(正しい):
pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
...その場合、上記は発生しません。ウェイクアップを見逃すことはありません。
(実際には、の後に自分自身を移動できますが、これによりスレッドのスケジューリングが最適化されなくなる可能性があり、条件自体を変更するため、このコードパスにすでにあるミューテックスをロックする必要があります)。pthread_cond_signal()
pthread_mutex_unlock()
pthread_signal_cond()
できますが、移動しない方がよいでしょう。呼び出している時点でpthread_signal_cond()
、条件自体を変更するためにミューテックスをロックする必要があると言った方が正しいかもしれません。