Help needed in Monitor.PulseAll()

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

13.10.2009 16:32:16
2 ОТВЕТА
РЕШЕНИЕ

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.

6
13.10.2009 18:02:07
Thanks Marc.I have seen your several post.They are excellent and simple to understand.Thanks you very much from bottom of my heart.
Prabugoel 13.10.2009 17:17:37
Marc one question.Here Signalling means "I am about to release" ?.
Prabugoel 13.10.2009 17:27:58

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);
}
3
17.10.2010 19:17:52
Thanks John.I am really greatful to you. :)
Prabugoel 13.10.2009 17:29:46
Won't the lock been automatically released? or do we need to specify it explicitly? i mean Monitor.Exit(lock)?
Prabugoel 13.10.2009 17:31:38
@Prabugoel If you use lock (obj) { }, the lock will be automatically released. If you use Monitor.Enter(), you have to explicitly Monitor.Exit(). How else would the runtime know when to release the lock? lock (obj) is just a short-hand for Enter and Exit.
bzlm 17.10.2010 09:50:30