3


1

以下の各同期オブジェクトはどのような状況下で使用されるべきですか?

  1. ReaderWriterロック

  2. セマフォ

  3. ミューテックス

3 Answer


5


  • wait()はpost()が呼び出されるたびに1回返されるので、セマフォはプロデューサ - コンシューマの基本的なモデルです。おそらくシグナルを除いた最も単純な形式のスレッド間メッセージです。 それらは、あるスレッドが別のスレッドに興味があることが(そして何回も)起こったことを伝え、そして最大で固定の有限数のユーザを持つことができるリソースへのアクセスを管理するために使用されます。 それらはマルチスレッドコードに必要な順序保証を提供します。

  • ミューテックスは彼らがブリキに関して言うことをする - 「相互排除」。 それらはあるリソースにアクセスする権利が一度にスレッド上でのみ "保持"されることを保証します。 これにより、マルチスレッドコードに必要な原子性と順序付けが保証されます。 ほとんどのOSでは、特に優先順位の逆転を避けるために、かなり洗練されたウェイターの動作も提供しています。

セマフォは相互排他を実装するために簡単に使用できることに注意してください。ただし、セマフォには「所有者スレッド」がないため、セマフォで優先順位の逆転を避けることはできません。 だから彼らは "ロック"を必要とするすべての用途には適していません。

  • ReaderWriterロックは、競合が多い場合、ほとんどのアクセスが読み取り専用で、保護されているデータ構造に対して同時読み取りが許可されている場合に、ミューテックスを最適化するものです。 そのような場合、排除は作家が関与しているときにだけ必要とされます - 読者はお互いから排除される必要はありません。 あるリーダーをライターに昇格させるには、他のすべてのリーダーは、ライターロックが取得される前に終了する(または、それらがライターになりたい場合は再試行の待機および中止を開始する)必要があります。 ReaderWriterのロックは、ミューテックスよりも追加のブックキーピングが原因で、速くない場合は遅くなる可能性があります。

  • 条件変数は、問題となっている条件がセマフォの場合のように「突かれた」場合や、ミューテックスの場合は「だれもそれを使用していない場合」よりも複雑です。リーダーライターロックのライター部分、またはリーダーライターロックのリーダー部分に「ライターが使用していない」。 それらはまた、待ち状態のスレッドが異なるとトリガ条件が異なる場合にも使用されますが、同じ状態の一部またはすべて(メモリ位置など)によって異なります。

  • スピンロックは、1つのプロセッサまたはコアで非常に短い時間(数サイクル程度)待つのに対して、別のコア(またはI / Oバスなどのハードウェアの一部)が同時に気になる作業を実行するときに使用します。約。 場合によっては、セマフォや割り込みなどの他のプリミティブよりもパフォーマンスが向上しますが、(現代のメモリモデルではロックフリーアルゴリズムは困難なため)慎重に使用する必要があります時期尚早の最適化です。

ところで、これらの答えはC#固有のものではありません(したがって、例えば、 "ほとんどのOS"に関するコメント)。 Richardは、C#では適切な場合は単純な古いロックを使用するべきであるという優れた点を指摘しています。 私は、モニタは1つのオブジェクトにまとめられたミューテックス/条件変数のペアであると思います。


1


私はそれらのそれぞれが「最高」になることができると言うでしょう - ユースケースによります;-)


1


簡単な答え:ほとんどありません。

最善のタイプのロックは、ロックを必要としないことです(共有される可変状態はありません)。

あなたがロックを必要とするならば、あなたが違う何かのために特別な必要性を持っているのでなければ(lockステートメントを介して)Monitorを試してみてください(その場合はOnebyoneの答えを見てください)

さらに、http://msdn.microsoft.com/library/system.threading.readerwriterlockslim [ReaderWriteLockSlim]をhttp://msdn.microsoft.com/library/system.threading.readerwriterlock [` ReaderWriterLock`]よりも好む(後者の公正さを要求するという非常にまれなケースでは)。