Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are Monitor.Pulse And Monitor.Wait advantages?

I'm kinda new to concurrent programming, and trying to understand the benefits of using Monitor.Pulse and Monitor.Wait .

MSDN's example is the following:

class MonitorSample
{
    const int MAX_LOOP_TIME = 1000;
    Queue   m_smplQueue;

    public MonitorSample()
    {
        m_smplQueue = new Queue(); 
    }
    public void FirstThread()
    {
        int counter = 0;
        lock(m_smplQueue)
        {
            while(counter < MAX_LOOP_TIME)
            {
                //Wait, if the queue is busy.
                Monitor.Wait(m_smplQueue);
                //Push one element.
                m_smplQueue.Enqueue(counter);
                //Release the waiting thread.
                Monitor.Pulse(m_smplQueue); 

                counter++;
            }
        }
    }
    public void SecondThread()
    {
        lock(m_smplQueue)
        {
            //Release the waiting thread.
            Monitor.Pulse(m_smplQueue);
            //Wait in the loop, while the queue is busy.
            //Exit on the time-out when the first thread stops. 
            while(Monitor.Wait(m_smplQueue,1000))
            {
                //Pop the first element.
                int counter = (int)m_smplQueue.Dequeue();
                //Print the first element.
                Console.WriteLine(counter.ToString());
                //Release the waiting thread.
                Monitor.Pulse(m_smplQueue);
            }
        }
    }
    //Return the number of queue elements.
    public int GetQueueCount()
    {
        return m_smplQueue.Count;
    }

    static void Main(string[] args)
    {
        //Create the MonitorSample object.
        MonitorSample test = new MonitorSample();           
        //Create the first thread.
        Thread tFirst = new Thread(new ThreadStart(test.FirstThread));
        //Create the second thread.
        Thread tSecond = new Thread(new ThreadStart(test.SecondThread));
        //Start threads.
        tFirst.Start();
        tSecond.Start();
        //wait to the end of the two threads
        tFirst.Join();
        tSecond.Join();         
        //Print the number of queue elements.
        Console.WriteLine("Queue Count = " + test.GetQueueCount().ToString());
    }
}

and i cant see the benefit of using Wait And Pulse instead of this:

    public void FirstThreadTwo()
    {
        int counter = 0;
        while (counter < MAX_LOOP_TIME)
        {
            lock (m_smplQueue)
            {
                m_smplQueue.Enqueue(counter);
                counter++;
            }
        }
    }
    public void SecondThreadTwo()
    {
        while (true)
        {
            lock (m_smplQueue)
            {
                    int counter = (int)m_smplQueue.Dequeue();
                    Console.WriteLine(counter.ToString());
            }
        }
    }

Any help is most appreciated. Thanks

like image 684
seren1ty Avatar asked Jul 04 '11 20:07

seren1ty


1 Answers

To describe "advantages", a key question is "over what?". If you mean "in preference to a hot-loop", well, CPU utilization is obvious. If you mean "in preference to a sleep/retry loop" - you can get much faster response (Pulse doesn't need to wait as long) and use lower CPU (you haven't woken up 2000 times unnecessarily).

Generally, though, people mean "in preference to Mutex etc".

I tend to use these extensively, even in preference to mutex, reset-events, etc; reasons:

  • they are simple, and cover most of the scenarios I need
  • they are relatively cheap, since they don't need to go all the way to OS handles (unlike Mutex etc, which is owned by the OS)
  • I'm generally already using lock to handle synchronization, so chances are good that I already have a lock when I need to wait for something
  • it achieves my normal aim - allowing 2 threads to signal completion to each-other in a managed way
  • I rarely need the other features of Mutex etc (such as being inter-process)
like image 83
Marc Gravell Avatar answered Sep 24 '22 02:09

Marc Gravell