现在,为什么Monitor需要一个条件变量?

时间:2014-07-03 10:42:36

标签: c# multithreading mutex monitor condition-variable

当您查看C#的Monitor类(lock关键字下面的类时,您会发现在其实现中您有一个条件变量和一个互斥锁。通过新线程进入获取互斥锁,如果尚未被另一个线程获取,则继续检查条件变量,如果是true,则线程可以继续,如果不是,则然后它被置于条件变量的线程休眠队列中,以便在条件变量再次变为真时被唤醒。

现在,为什么Monitor需要条件变量?它检查什么条件?我已阅读有关Monitor的wikipedia's文章,但我无法推断它会等待的条件是什么?

它不是由lockMonitor的用户指定的内容,而是一些内部变量。通过锁定看object作为参数,supposedly only for identifying锁定。

这就像使用AutoResetEventMutex并获取互斥锁上的锁定,然后查看AutoResetEvent是否设置为已发出信号?

我不确定为什么Monitor需要一个条件变量,当一个线程等待获取一个互斥锁时,它是否也会在互斥体被释放时被唤醒? (OS调度程序可能是唤醒的那个)

我希望这是有道理的,而且有人可以在我的理解中找到差距。

1 个答案:

答案 0 :(得分:0)

这是CLR 4.0中引入的Monitor.Enter方法的重载,用于纠正一个微妙的漏洞。

this website中对此进行了解释。

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

考虑在Monitor.Enter的实现中抛出异常的(不太可能的)事件,或者在Monitor.Enter和try块的调用之间(可能是由于在该线程上调用Abort或者OutOfMemoryException)被抛出)。在这种情况下,可能会或可能不会采取锁定。如果锁定,它将不会被释放 - 因为我们永远不会进入try / finally块。这将导致泄漏锁定。

     

为了避免这种危险,CLR 4.0的设计人员将以下重载添加到Monitor.Enter