views:

267

answers:

2

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.

+2  A: 

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);
}
John Gietzen
Thanks John.I am really greatful to you. :)
Prabugoel
Won't the lock been automatically released? or do we need to specify it explicitly? i mean Monitor.Exit(lock)?
Prabugoel
@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
+5  A: 

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.

Marc Gravell
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
Marc one question.Here Signalling means "I am about to release" ?.
Prabugoel
No; will update...
Marc Gravell