http://www.codeproject.com/Articles/28785/Thread-synchronization-Wait-and-Pulse-demystifiedMonitor.Pulse&ウェイト - 予期しない動作
キュー:
レディキューは 特定のロックのために待機しているスレッドのコレクションです。 Monitor.Waitメソッドは、別のキュー、 待機キューを導入します。これは、パルスが別個の がロックを獲得するのを待つのを待つときに必要です。準備完了キューと同様に、待ちキュー はFIFOです。
推奨パターン:
これらのキューは予期しない動作を引き起こす可能性があります。パルスが発生すると、待ちキューの先頭の が解放され、準備完了キュー に追加されます。ただし、レディキューに他のスレッドがある場合は、 は解放されたスレッドの前にロックを取得します。ロックを取得するスレッドは、パルススレッドが依存する状態 を変更できるため、これは の問題です。解決策は、ロック文内にある 条件を使用することです。
* Q =キュー。
それで、私はPulse
と呼んだとき、それが終わる前に2つのことをすることを理解しています。まず、待機中のQからREADY Qへのスレッドを1つ取り除きます。次に、Ready Qの1つのスレッド(そのスレッドが誰であるかを知らないで)がロックを取得するようにします。誰がロックを取得したか(何らかの理由で待機中のQから来たスレッドまたは準備完了したQにあったスレッド)は気にしません。
私はそのことについて権利だ場合は、なぜは、問題を解決する手助けMonitor.Wait
前while
を入れている(問題 - パルスが待機Qから来たスレッドがロックを取得していない場合でも終了)?
。 Monitor.Pulse
の目的について私が正しいかどうか教えてください。
b。もしあなたが作るPulse
たびに - あなたはプロデューサー/コンシューマ・キューを作成しようとしている想像し
class Program
{
static Queue<int> queue = new Queue<int>();
static object someMonitor = new object();
static void Main(string[] args)
{
Thread Thread1 = new Thread(WorkAlltheTime);
Thread1.Name = "Thread1";
Thread Thread2 = new Thread(WorkAlltheTime);
Thread2.Name = "Thread2";
Thread Thread3 = new Thread(WorkOnce);
Thread3.Name = "Thread3";
Thread1.Start();
Thread2.Start();
Thread.Sleep(1000);
Thread3.Start();
Console.ReadLine();
}
static void WorkAlltheTime()
{
Console.WriteLine("Came in to Ready Q: " + Thread.CurrentThread.Name);
lock (someMonitor)
{
Console.WriteLine("Came out from Ready Q: " + Thread.CurrentThread.Name);
// Broken!
while (queue.Count == 0)
{
Console.WriteLine("Came in to Waiting Q: " + Thread.CurrentThread.Name);
Monitor.Wait(someMonitor);
Console.WriteLine("Came out from Waiting Q: " + Thread.CurrentThread.Name);
}
queue.Dequeue();
Console.WriteLine("Thread: "+Thread.CurrentThread.Name+" Pulled Out");
}
}
static void WorkOnce()
{
lock (someMonitor)
{
queue.Enqueue(1);
Monitor.Pulse(someMonitor);
}
}
}
ありがとう、私はあなたの例の完全なコードを書いて、あなたの説明で私は90回それをテストし、私は今完全に理解しています。ありがとう、アギアン! –