开发者

Help needed in Monitor.PulseAll()

can anybody explain me with simple example to开发者_如何学Go handle Monitor.PulseAll().I have already gone some examples from this stackoverflow.As i am a beginner i feel those are above my head.


How about (to show the interaction):

static void Main()
{
    object obj = new object();
    Console.WriteLine("Main thread wants the lock");
    lock (obj)
    {
        Console.WriteLine("Main thread has the lock...");
        ThreadPool.QueueUserWorkItem(ThreadMethod, obj);
        Thread.Sleep(1000);
        Console.WriteLine("Main thread about to wait...");
        Monitor.Wait(obj); // this releases and re-acquires the lock
        Console.WriteLine("Main thread woke up");
    }
    Console.WriteLine("Main thread has released the lock");
}
static void ThreadMethod(object obj)
{
    Console.WriteLine("Pool thread wants the lock");
    lock (obj)
    {
        Console.WriteLine("Pool thread has the lock");
        Console.WriteLine("(press return)");
        Console.ReadLine();
        Monitor.PulseAll(obj); // this signals, but doesn't release the lock
        Console.WriteLine("Pool thread has pulsed");
    }
    Console.WriteLine("Pool thread has released the lock");
}

Re signalling; when dealing with Monitor (aka lock), there are two types of blocking; there is the "ready queue", where threads are queued waiting to execute. On the line after Console.WriteLine("Pool thread wants the lock"); the pool queue enters the ready queue. When the lock is released a thread from the ready queue can acquire the lock.

The second queue is for threads that need waking; the call to Wait places the thread in this second queue (and releases the lock temporarily). The call to PulseAll moves all threads from this second queue into the ready queue (Pulse moves only one thread), so that when the pool thread releases the lock the main thread is allowed to pick up the lock again.

It sounds complex (and perhaps it is) - but it isn't as bad as it sounds... honestly. However, threading code is always tricky, and needs to be approached with both caution and a clear head.


Monitor.Wait() will always wait for a pulse.

So, the principal is:

  1. When in doubt, Monitor.Pulse()
  2. When still in doubt, Monitor.PulseAll()

Other than that, I'm not sure what you are asking. Could you please elaborate?

Edit:
Your general layout should be:

Monitor.Enter(lock);

try
{
    while(!done)
    {
        while(!ready)
        {
            Monitor.Wait(lock);
        }

        // do something, and...

        if(weChangedState)
        {
             Monitor.Pulse(lock);
        }
    }
}
finally
{
    Monitor.Exit(lock);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜