どちらも同じ目的を果たしているようです。いつ私はどちらか一方を選びましたか?
4 に答える
何かを行うために多数のイベントの 1 つまたはすべてを待機しているスレッドがある場合は、イベントを使用します。
データ構造にアクセスできるスレッド数を制限して、データ構造へのアクセスを制限する場合は、モニターを使用します。
通常、モニターはリソースを保護しますが、イベントは、アプリケーションのシャットダウンなど、何かが起こっていることを知らせます。
また、イベントには名前を付けることができます (OpenExisting メソッドを参照)。これにより、さまざまなプロセス間での同期に使用できます。
私の意見では、可能であれば Monitor を使用することをお勧めします。Monitor.Wait と Monitor.Pulse/PulseAll はスレッド間のシグナル伝達に使用されますが (Manual/AutoResetEvent と同様)、Monitor の方が高速であり、ネイティブ システム リソースを使用しません。また、明らかに Monitor はユーザー モードで実装され、管理されますが、Manual/AutoResetEvents はカーネル モードに切り替えて、待機ハンドルを使用するネイティブの win32 呼び出しに p/invoke する必要があります。
たとえば、Manual/AutoResetEvent を使用して、名前付きイベントを使用できるプロセス間でシグナルを送信する必要がある場合があります。アプリ内のネイティブ スレッドにシグナルを送信すると思います。
私は、スレッド化に関するこの優れた記事で読んだことを逆流させているだけです。
記事全体を読む価値はありますが、リンクをクリックすると、イベントの詳細と待機/パルスの監視を行う待機ハンドルのセクションに移動します。
クリティカル セクションを必要とせずWaitHandle
にスレッドでバイナリ シグナルを送受信する場合は、 を使用します。一方、クリティカルセクションが必要です。BCLのほとんどの同期メカニズムと同様に、あなたが言及した2つを使用する方法にはいくつかの重複があります。しかし、それらが同じ目的を果たしているとは一瞬たりとも考えないでください。Monitor.Wait
Monitor.Pulse
Monitor.Wait
MREやMonitor.Pulse
ARE よりもはるかに原始的な同期メカニズムです。実際、MRE または ARE は、Monitor
クラスだけを使用して構築できます。理解すべき最も重要な概念は、Monitor.Wait
とWaitHandle.WaitOne
メソッドの違いです。これは、スレッドがアイドル状態Wait
になり、 aまたはそれぞれのor呼び出しにのみ応答することを意味します。しかし、これは大きな違いであり、クリティカル セクションを残して、アトミックな方法で再取得します。単にこれを行うことはできません。これらの同期メカニズムが使用できるシナリオを定義するのは、これらの同期メカニズムの動作方法にとって非常に根本的な違いです。WaitOne
WaitSleepJoin
Thread.Interrupt
Pulse
Set
Wait
WaitOne
ほとんどの場合、MRE または ARE を選択します。これらは、あるスレッドが別のスレッドからシグナルを受信する必要があるほとんどの状況を満たします。ただし、独自のシグナリング メカニズムを作成する場合は、 と を使用する必要がありWait
ますPulse
。しかし、繰り返しになりますが、.NET BCL には、既にカバーされている一般的なシグナリング メカニズムのほとんどが含まれています。次のシグナリング メカニズムはすでに存在します1。
- ManualResetEvent (または ManualResetEventSlim)
- AutoResetEvent
- セマフォ (または SemaphoreSlim)
- イベント待機ハンドル
- カウントダウンイベント
- バリア
1BlockingCollection
クラスに佳作が贈られる。それ自体はシグナリング メカニズムではありませんが、シグナリング メカニズムの品質に加えて、信号にデータを添付できるという利点があります。この場合、シグナルはアイテムがコレクションで利用可能であることを意味し、そのシグナルに関連付けられたデータはアイテム自体です。
このチュートリアルでは、知っておくべきことについて詳しく説明しています: http://www.albahari.com/threading/
特に、これは XXXResetEvent クラス (
http://www.albahari.com/threading/part2.aspx ) をカバーします。
これは Wait/Pulse をカバーします: http://www.albahari.com/threading/part4.aspx#_Wait_and_Pulse