Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 564
Prabugoel Avatar asked Dec 17 '25 00:12

Prabugoel


2 Answers

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.

like image 58
Marc Gravell Avatar answered Dec 19 '25 12:12

Marc Gravell


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);
}
like image 32
John Gietzen Avatar answered Dec 19 '25 12:12

John Gietzen