[解決済み] 条件付き変数とセマフォの比較
質問
セマフォを使うタイミングと条件変数を使うタイミングは?
どのように解決するのですか?
ロックは相互排除のために使用されます。 コードの一部がアトミックであることを保証したいとき、その周りにロックを置きます。 理論的にはバイナリセマフォを使用してこれを行うことができますが、それは特殊なケースです。
セマフォと条件変数はロックによる相互排除の上に構築され、共有リソースへの同期されたアクセスを提供するために使用されます。 これらは同様の目的で使用することができます。
条件変数は一般に、リソースが利用可能になるのを待つ間のビジーウェイト(条件をチェックしながら繰り返しループすること)を避けるために使用されます。 例えば、キューが空になるまで先に進めないスレッド(または複数のスレッド)がある場合、ビジーウェイトのアプローチは、単に次のようなことをすることです。
//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つの選択肢の間には重複があります。 セマフォまたは条件変数 (または条件変数のセット) の両方が目的を果たすことができる多くのシナリオがあります。 セマフォと条件変数はどちらもロックオブジェクトに関連付けられ、相互排除を維持するために使用されますが、スレッドの実行を同期させるためにロックの上に追加機能を提供します。 どちらがあなたの状況にとって最も理にかなっているかは、ほとんどあなた次第です。
これは必ずしも最も技術的な説明ではありませんが、私の頭の中ではそのように理解されています。
関連
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] プロセスとスレッドの違いは何ですか?
-
[解決済み] ThreadLocal変数はいつ、どのように使用すればよいですか?
-
[解決済み] ロック、ミューテックス、セマフォの違いは何ですか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】セマフォとモニター、何が違うの?
-
[解決済み] 技術的に、なぜErlangのプロセスはOSのスレッドよりも効率的なのですか?
-
[解決済み] ロックされていないミューテックスをロックすることは、どの程度効率的ですか?ミューテックスのコストは?
-
[解決済み] 非同期とマルチスレッド - 違いはあるのか?
-
[解決済み] 条件付き変数とセマフォの比較
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
コレクションが変更されたため、列挙操作が実行できない場合がある Error
-
[解決済み] レースコンディションとは何ですか?
-
[解決済み] スレッドは何本までならOK?
-
[解決済み] ロックされていないミューテックスをロックすることは、どの程度効率的ですか?ミューテックスのコストは?
-
[解決済み] デッドロックとは何ですか?
-
[解決済み] マルチスレッドに代わるNode JSを把握する
-
[解決済み] スレッドコンテキストスイッチとプロセスコンテキストスイッチの比較
-
[解決済み] スレッドセーフとは何ですか?
-
[解決済み] コンパイル時の-pthreadと-lpthreadの違いについて
-
[解決済み] 条件付き変数とセマフォの比較