1. ホーム
  2. c++

[解決済み] mutexをロックせずにpthread_cond_signalを呼び出す。

2023-03-23 15:44:56

質問

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

pthread_cond_signal()ルーチンは、次のように使用されます。 を待っている他のスレッドにシグナルを送る(または起動する)ために使用されます。 を待っている他のスレッドにシグナルを送る(起こす)ために使用されます。 ルーチンを使用します。このルーチンは mutexがロックされた後に呼び出される必要があります。 のために、mutexをロック解除しなければなりません。 pthread_cond_wait()ルーチンが完了するためには、mutexをアンロックする必要があります。 ルーチンが完了するために、mutex をアンロックしなければなりません。

私の質問は、次のように呼び出すことは問題ないでしょうか? pthread_cond_signal または pthread_cond_broadcast メソッドを使用すると、ミューテックスをロックせずに済むのですか?

どのように解決するのですか?

条件とシグナルを変更するコードパスでミューテックスをロックしない場合、ウェイクアップが失われることがあります。 このプロセスのペアを考えてみましょう。

プロセス 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() しかし、これはスレッドのスケジューリングが最適でなくなる可能性があり、条件自体を変更するため、このコードパスではすでにmutexをロックしていることになります)。