2009-07-09 7 views
8

pthread_cond_tではmutexを関連付ける必要があります。条件を通知するときは、mutexを保持した状態でpthread_cond_broadcastを呼び出しますか?

などのコードを見たことがあります。
pthread_mutex_lock(&mutex); 

//code that makes condition true 

pthread_cond_broadcast(&cond); 
pthread_mutex_unlock(&mutex); 

pthread_mutex_lock(&mutex); 

//code that makes condition true 

pthread_mutex_unlock(&mutex); 
pthread_cond_broadcast(&cond); 

どちらが適切ですか? (それは重要ですか?)

答えて

13

シンクが何をしているのか(および他のソース)によって異なります。

2番目のコードサンプルでは、​​アンロックとブロードキャストの間に、他のスレッドの束が来て、条件を再びfalseにするいくつかの組み合わせを行う可能性があります。あなたは無意識に放送します。条件を変更したときと同じウェイターのセットを持っているとは限りません。これはあなたのデザインに影響するかもしれません。

まともなシンクは、特にブロードキャストを使用している場合に、目が覚まれ、条件が偽であるかどうかに気を付けるべきではありません。 「true」への条件の変更がブロードキャストに続いている限り、適切に書かれたシンクでは、ロックの有無にかかわらず条件変数をブロードキャストできます。

私はそれが本当に問題ではないと思っていますが、個人的にはそれを心配することを避けるために、ロックを保持して放送していました。 「原子の変化と信号」は、「変化した後、ある時間後、信号」と比較して、ホワイトボード上の状態図を単純化するかもしれません。

どちらも適切です(ミューテックスを使わずに待機しているのとは異なりますが、許可されていません)が、2番目のケースで間違っている可能性が出てくるのは難しくないと思います。最初は間違っています。彼らはおそらく若干の珍しいものをやっているウェイターを関与させなければならないでしょう。

仕様では、「予測可能なスケジューリング動作が必要な場合、そのミューテックスはpthread_cond_broadcast()またはpthread_cond_signal()を呼び出すスレッドによってロックされます。

http://www.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html

+0

私はあなたの答えを見つけました。私はあなたのリンクをたどりました。私は、あなたが引用したビットが以前のビットに関連していると思います。「複数のスレッドが条件変数でブロックされている場合、スケジューリングポリシーはスレッドのブロック解除順序を決定します。 – wilx

+0

@wilx:はい、私の心配は "予測不可能なスケジューリングの動作"によって許可されているものです。たとえば、スケジューラに文書化されている、またはオプションがあると、mutexと条件変数がFIFOベースで起床するスレッドを選択するとします。 '' pthread_cond_signal''の呼び出し側がmutexを保持していない場合、その動作がFIFOであるとは予想されませんか?私はそう考えていますが、私は "予測可能"という正式な定義を知らないので、それがわかりにくいのです。 RTシステムを除いて、私はいつもスケジューリングを予測不可能なものとして扱いますが、私はそれが奇妙になることを望んでいません。 –

+0

ロック解除前またはロック解除後にブロードキャストを送信するかどうかは重要ではありません。非常に難しいことですが、ロックを解除した後に信号を移動するとコードが壊れます。 –