セマフォは、他の用途もありますが、生産者/消費者モデルにきれいに適合します。プログラムロジックは、待機回数に対して適切な数の投稿が行われるようにする責任があります。セマフォを投稿し、まだ誰もそれを待っていない場合、彼らが待つとすぐに続行します。セマフォのカウント値で説明できるような問題であれば、セマフォで簡単に解決できるはずです。
条件変数は、いくつかの点でもう少し寛容です。たとえば、cond_broadcastを使用して、プロデューサーが何人いるかを知らなくても、すべてのウェイターをウェイクアップできます。そして、誰も待っていない状態でcondvarをcond_signalすると、何も起こりません。これは、リスナーが興味を持ってくれるかどうかわからない場合に便利です。また、リスナーは待機する前にミューテックスを保持した状態で常に状態を確認する必要があるのもそのためです。確認しないと、信号を見逃し、次の信号までウェイクアップしない可能性があります(これは決して起こり得ません)。
したがって、条件変数は、状態が変更されたことを関係者に通知するのに適しています。ミューテックスを取得し、状態を変更し、条件を通知(またはブロードキャスト)して、ミューテックスを解放します。これがあなたの問題を説明しているなら、あなたはcondvar領域にいます。さまざまなリスナーがさまざまな状態に関心がある場合は、ブロードキャストするだけで、それぞれが順番にウェイクアップし、目的の状態が見つかったかどうかを確認します。そうでない場合は、もう一度待ちます。
ミューテックスとセマフォを使ってこの種のことを試みるのは、実に非常に危険です。問題は、ミューテックスを取得し、状態を確認してから、セマフォが変更されるのを待つ場合に発生します。ミューテックスをアトミックに解放してセマフォを待機できない限り(pthreadではできません)、ミューテックスを保持しながらセマフォを待機することになります。これはミューテックスをブロックします。つまり、他の人があなたが気にかけている変更を行うためにミューテックスを取得することはできません。そのため、特定の要件に応じた方法で別のミューテックスを追加したくなるでしょう。そして多分別のセマフォ。結果は、一般的に、有害な競合状態を伴う誤ったコードになります。
cond_waitを呼び出すとミューテックスが自動的に解放され、他のユーザーが使用できるように解放されるため、条件変数はこの問題を回避します。cond_waitが戻る前に、ミューテックスが回復します。
IIRCは、セマフォのみを使用して一種のcondvarを実装することは可能ですが、condvarを使用するために実装しているミューテックスにtrylockが必要な場合、それは深刻なヘッドスクラッチャーであり、時間制限のある待機がなくなります。推奨されません。したがって、condvarで実行できることはすべてセマフォで実行できると思い込まないでください。さらに、もちろん、ミューテックスは、セマフォに欠けている優れた動作、主に優先順位の逆転の回避を行うことができます。