条件とシグナルを変更するコードパスでミューテックスをロックしないと、ウェイクアップが失われる可能性があります。次のプロセスのペアを検討してください。
プロセス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()