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

本文关键字:一个 条件 变量 为什么 Monitor 现在 | 更新日期: 2023-09-27 18:11:20

当您查看c#的Monitor类(lock关键字的底层)时,您会发现在它的实现中有一个条件变量和一个互斥锁。互斥锁被一个新线程获取,如果还没有被另一个线程获取,然后它继续检查条件变量,如果它是true,线程可以继续,如果它不是真的,那么它被放在条件变量的线程睡眠队列中,以便在条件变量再次变为真时被唤醒。

现在,为什么Monitor需要一个条件变量?它检查什么条件?我已经阅读了维基百科上关于Monitor的文章,我还没能推断出它会在什么条件下等待?

它不是lockMonitor的用户指定的东西,而是一些内部变量。看到object作为锁的参数,应该只是用来标识锁。

这是否就像使用AutoResetEventMutex并获得互斥锁,然后查看AutoResetEvent是否设置为有信号?

我不确定为什么Monitor需要一个条件变量,当一个线程等待获得互斥锁时,当互斥锁被释放时,它不也会被唤醒吗?(操作系统调度器可能是执行唤醒的那个)

我希望这是有意义的,并且有人可以找到我理解上的差距

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

这是Monitor的一个过载。CLR 4.0中引入的输入方法,以纠正一个微妙的漏洞。

本网站对此进行了解释。

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

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

为了避免这种危险,CLR 4.0的设计者向Monitor添加了以下重载。输入