89

pthread_cond_signalを呼び出す前にミューテックスをロックし、呼び出し後にミューテックスをロック解除する必要があることをどこかで読みました。

pthread_cond_signal() ルーチンは、条件変数を待機している別のスレッドにシグナルを送る (またはウェイクアップする) ために使用されます。これはミューテックスがロックされた後に呼び出され、pthread_cond_wait() ルーチンが完了するためにミューテックスのロックを解除する必要があります。

私の質問は、ミューテックスをロックせずにpthread_cond_signalまたはpthread_cond_broadcastメソッドを呼び出しても問題ないのでしょうか?

4

3 に答える 3

158

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

プロセスA:

pthread_mutex_lock(&mutex);
while (condition == FALSE)
    pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);

プロセス B (不正解):

condition = TRUE;
pthread_cond_signal(&cond);

次に、次のような命令のインターリーブを考えてみましょconditionFALSE

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()

于 2010-12-31T03:38:23.350 に答える
54

このマニュアルによると:

pthread_cond_broadcast()または pthread_cond_signal()関数 は、スレッドが待機中に条件変数を呼び出す か関連付けたミューテックスを現在所有しているかどうかに関係なく、スレッドによって呼び出される場合があります。ただし、予測可能なスケジューリング動作が必要な場合、そのミューテックスは or を呼び出すスレッドによってロックされます。pthread_cond_wait()pthread_cond_timedwait()pthread_cond_broadcast()pthread_cond_signal()

予測可能なスケジューリング動作ステートメントの意味は、Dave Butenhof ( Programming with POSIX Threadsの著者) によって comp.programming.threads で説明されており、ここから入手できます。

于 2010-12-28T07:48:07.770 に答える