Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monitor.Wait - while or if?

Currently, I'm learning for a multithreading exam. I read the good threading article of albahari. I've got a question at the monitor usage - why is here used a loop in place of an if?

lock (_locker)
{
  while (!_go) //why while and not if?
    Monitor.Wait (_locker);  // _lock is released
  // lock is regained
  ...
}

I think, that an if would be sufficient.

I'm afraid, that I don't understand the article completely.

//Edit Example-Code:

class SimpleWaitPulse
{
  static readonly object _locker = new object();
  static bool _go;

  static void Main()
  {                                // The new thread will block
    new Thread (Work).Start();     // because _go==false.

    Console.ReadLine();            // Wait for user to hit Enter

    lock (_locker)                 // Let's now wake up the thread by
    {                              // setting _go=true and pulsing.
      _go = true;
      Monitor.Pulse (_locker);
    }
  }

  static void Work()
  {
    lock (_locker)
      while (!_go)
        Monitor.Wait (_locker);    // Lock is released while we’re waiting

    Console.WriteLine ("Woken!!!");
  }
}
like image 234
bitsmuggler Avatar asked Jan 16 '12 19:01

bitsmuggler


2 Answers

It just depends on the situation. In this case the code is just waiting for _go to be true.

Every time _locker is pulsed it will check to see if _go has been set to true. If _go is still false, it will wait for the next pulse.

If an if was used instead of a while, it would only wait once (or not at all if _go was already true), and would then continue on after a pulse, regardless of the new state of _go.

So how you use Monitor.Wait() depends entirely on your specific needs.

like image 122
Igby Largeman Avatar answered Sep 27 '22 16:09

Igby Largeman


It really just depends on the situation. But first, we need to clarify how Monitors work. When a thread proceeds to signal a thread through Monitor.Pulse(), there is usually no guarantee that the signaled thread will actually run next. This means that it is possible for other threads to run before the signaled thread and change the condition under which it was okay for the signaled thread to proceed. This means that the signaled thread still needs to check if is safe for it to proceed after being woken up (ie the while loop). However, certain rare synchronization problems allow you to make the assumption that once a thread has been signaled to wake up (ie Monitor.Pulse()), no other thread has the ability to change the condition under which it is safe to proceed (ie. the if condition).

like image 43
Nadir Muzaffar Avatar answered Sep 27 '22 17:09

Nadir Muzaffar