2

When you look at C#'s Monitor class, the one used under the hood of the lock keyword, you'll find that in its implementation you have a condition variable and a mutex. The mutex is acquired by a new thread entering, if not already acquired by another thread, and then it goes on to check the condition variable, if it is true, the thread can proceed, if it isn't true, then it gets put on the condition variable's thread sleep queue, in order to be woken when the condition variable becomes true again.

Now, why does Monitor need a condition variable? What condition does it check? I have read through wikipedia's article on Monitor and I haven't been able to deduce what condition it would wait on?

Its not something specified by the user of lock or Monitor, but some internal variable. Seeing that the object taking as argument by lock, is supposedly only for identifying the lock.

Is this just like using a AutoResetEvent and a Mutex and acquiring a lock on the Mutex and then seeing if the AutoResetEvent is set to signalled?

I'm not sure I get why Monitor needs a condition variable, when a thread waits to acquire a mutex, doesn't it also get woken up when the mutex is released? (The OS scheduler being the one that probably does the waking)

I'm hoping that this makes sense, and that someone can find the gap in my understanding.

Community
  • 1
  • 1
Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
  • This might shed some light: http://ericlippert.com/2009/03/06/locks-and-exceptions-do-not-mix/ – Davin Tryon Jul 03 '14 at 10:53
  • 3
    Monitor doesn't use a condition variable at all. Maybe it is helpful to pretend it has one to grok the way it works. But the implementation is very different, otherwise [buried inside the CLR](http://stackoverflow.com/a/14923685/17034). – Hans Passant Jul 03 '14 at 11:07

1 Answers1

0

This is an overload of the Monitor.Enter method introduced in CLR 4.0 to correct a subtle vulnerability.

This is explained in this website.

Monitor.Enter (_locker);
try
{
  if (_val2 != 0) Console.WriteLine (_val1 / _val2);
  _val2 = 0;
}
finally { Monitor.Exit (_locker); }

Consider the (unlikely) event of an exception being thrown within the implementation of Monitor.Enter, or between the call to Monitor.Enter and the try block (due, perhaps, to Abort being called on that thread — or an OutOfMemoryException being thrown). In such a scenario, the lock may or may not be taken. If the lock is taken, it won’t be released — because we’ll never enter the try/finally block. This will result in a leaked lock.

To avoid this danger, CLR 4.0’s designers added the following overload to Monitor.Enter

alexandrekow
  • 1,927
  • 2
  • 22
  • 40