1. ホーム
  2. multithreading

[解決済み] 条件付き変数とセマフォの比較

2022-07-04 22:15:52

質問

セマフォを使うタイミングと条件変数を使うタイミングは?

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

ロックは相互排除のために使用されます。 コードの一部がアトミックであることを保証したいとき、その周りにロックを置きます。 理論的にはバイナリセマフォを使用してこれを行うことができますが、それは特殊なケースです。

セマフォと条件変数はロックによる相互排除の上に構築され、共有リソースへの同期されたアクセスを提供するために使用されます。 これらは同様の目的で使用することができます。

条件変数は一般に、リソースが利用可能になるのを待つ間のビジーウェイト(条件をチェックしながら繰り返しループすること)を避けるために使用されます。 例えば、キューが空になるまで先に進めないスレッド(または複数のスレッド)がある場合、ビジーウェイトのアプローチは、単に次のようなことをすることです。

//pseudocode
while(!queue.empty())
{
   sleep(1);
}

この問題は、このスレッドが繰り返し条件をチェックすることによって、プロセッサの時間を浪費していることです。 代わりに、リソースが利用可能であることをスレッドに伝えるためにシグナルを送ることができる同期変数を用意してはどうでしょうか?

//pseudocode
syncVar.lock.acquire();

while(!queue.empty())
{
   syncVar.wait();
}

//do stuff with queue

syncVar.lock.release();

おそらく、他のどこかでキューから物を取り出すスレッドがあるはずです。 キューが空になったとき、そのスレッドは syncVar.signal() で眠っているランダムなスレッドを呼び出すことができます。 syncVar.wait() (あるいは、通常は signalAll() または broadcast() メソッドを使って待機している全てのスレッドを起動します)。

私は一般的に、1つ以上のスレッドが1つの特定の条件(例えば、キューが空であること)で待機しているときに、このような同期変数を使用します。

セマフォも似たような使い方ができますが、利用可能なものの整数値に基づいて利用可能になったり利用不可能になったりする共有リソースがあるときに、よりよく使われるのだと思います。 セマフォは、生産者がリソースを割り当て、消費者がそれを消費するようなプロデューサー/コンシューマーの状況に適しています。

ソーダの自動販売機があった場合を考えてみてください。 ソーダの自動販売機は1台しかなく、それは共有リソースです。 マシンの在庫を維持する責任を負うベンダー(生産者)であるスレッドが1つあり、マシンからソーダを取り出したいバイヤー(消費者)であるスレッドがNつあります。 マシン内のソーダの数は、セマフォを駆動するための整数値です。

ソーダマシンにやってくるすべての買い手(消費者)スレッドは、セマフォを呼び出します。 down() メソッドを呼び出してソーダを取ります。これは、マシンからソーダを取得し、利用可能なソーダのカウントを1だけ減少させます。 down() ステートメントを過ぎても問題なく実行されます。ソーダがない場合、スレッドはここでスリープし、ソーダが再び利用可能になったとき (マシンにもっとソーダがあるとき) に通知されるのを待ちます。

ベンダー (生産者) のスレッドは、本質的にソーダマシンが空になるのを待つことになります。 最後のソーダがマシンから取り出されると、ベンダーは通知を受けます (そして、1 人以上の消費者がソーダを取り出すのを潜在的に待っています)。 ベンダーはセマフォでソーダマシンを補充します。 up() メソッドを使用してソーダを補充すると、利用可能なソーダの数は毎回インクリメントされ、それによって待機中の消費者スレッドはより多くのソーダが利用可能であることを通知されるでしょう。

このメソッドは wait()signal() メソッドは、同期化変数の down()up() の操作で、セマフォの

確かに、2つの選択肢の間には重複があります。 セマフォまたは条件変数 (または条件変数のセット) の両方が目的を果たすことができる多くのシナリオがあります。 セマフォと条件変数はどちらもロックオブジェクトに関連付けられ、相互排除を維持するために使用されますが、スレッドの実行を同期させるためにロックの上に追加機能を提供します。 どちらがあなたの状況にとって最も理にかなっているかは、ほとんどあなた次第です。

これは必ずしも最も技術的な説明ではありませんが、私の頭の中ではそのように理解されています。