セマフォとミューテックス/条件変数は、スレッド間またはプロセス間での使用に適した、優れた非常に高性能なプリミティブです。
これらはすべて、共有メモリに対して実行されるテスト アンド セットまたはその他のアトミック操作のアイデア (および通常は現実) に基づいています。
プロセスをネットワーク経由で分散することを期待している場合、セマフォとミューテックスは適していない可能性があります。これらは 1 台のマシンでしか機能しません。パイプとソケットは、より一般的にネットワーク拡張可能です。
ミューテックス、条件変数、およびセマフォの簡単な要約:
ミューテックス
ミューテックスは、ロックまたはロック解除できるプリミティブです。ロックしたプロセス/スレッドは、ロックを解除する必要があります。この所有権の側面により、オペレーティング システムは、優先度の継承や優先度上限プロトコル (優先度の逆転を回避するため) などの興味深い最適化を適用できます。 ただし、ミューテックスにはカウントが関連付けられていません。一般に、すでにロックされているミューテックスをロックすることはできず、「2回ロックされた」というメモリを保持できません(これを許可する拡張機能がいくつかあると思いますが、どこでも利用できるわけではありません)
条件変数
ミューテックスは、MUTual EXclusion に最適です。しかし、相互排除しているオブジェクトに関連付けられた条件でブロックする必要がある場合はどうでしょうか? これには、条件変数 (CV) を使用します。CV はミューテックスに関連付けられています。たとえば、プロセスがアクセスしたい入力データのキューがあるとします。ミューテックスを取得して、干渉を恐れずにキューを確認できるようにします。ただし、キューが空であることを検出し、何かがキューに入るのを待ちたいと考えています。したがって、「キューが空ではない」条件変数で待機します。ここで興味深いのは、CV がミューテックスに関連付けられているため、ミューテックスが自動的に再取得されることです。条件変数が通知されると。したがって、プロセスが CV を待機した後にウェイクアップすると、プロセスは再びキューに排他的にアクセスできることを認識します。わからないのは、キューに実際に何かがあるかどうかです-おそらく2つのプロセスがCVで待機していました-1つが入ってきました-そして、最初の優先度が入り、2番目のものが目覚める前に「もの」をキューから外しました。したがって、履歴書を使用するときはいつでも、次のように条件を再確認する必要があります。
mutex_enter(m);
while (! condition) {
cond_wait(m, c); // drop mutex lock; wait on cv; reacquire mutex
}
//processing related to condition
mutex_exit(m);
セマフォ
OK、それはミューテックスと条件変数です。セマフォはより単純です。これらは、任意のプロセスで増減できます。それらにはメモリがあり、カウントされるため、それらを使用して、条件がいくつ発生したかを判断できます。条件変数ではそうではありません。また、セマフォはあるプロセスによってデクリメントされ、別のプロセスによってインクリメントされる可能性があるため、所有権の側面を持たないため、優先順位の継承や優先順位の逆転を回避することはできません。
最後に、これらのメカニズムはすべて、効率的な実装のために共有メモリを必要とします。これで問題ないかもしれませんが、アプリケーションが最終的に配布される可能性があると思われる場合は、ミューテックス、条件変数、およびセマフォが適していない可能性があることに注意してください。パイプとソケットは、オーバーヘッドがはるかに高くなりますが、ネットワーク上でかなり簡単に拡張できる可能性があります。