现在,为什么Monitor需要一个条件变量
本文关键字:一个 条件 变量 为什么 Monitor 现在 | 更新日期: 2023-09-27 18:11:20
当您查看c#的Monitor
类(lock
关键字的底层)时,您会发现在它的实现中有一个条件变量和一个互斥锁。互斥锁被一个新线程获取,如果还没有被另一个线程获取,然后它继续检查条件变量,如果它是true
,线程可以继续,如果它不是真的,那么它被放在条件变量的线程睡眠队列中,以便在条件变量再次变为真时被唤醒。
现在,为什么Monitor
需要一个条件变量?它检查什么条件?我已经阅读了维基百科上关于Monitor的文章,我还没能推断出它会在什么条件下等待?
它不是lock
或Monitor
的用户指定的东西,而是一些内部变量。看到object
作为锁的参数,应该只是用来标识锁。
这是否就像使用AutoResetEvent
和Mutex
并获得互斥锁,然后查看AutoResetEvent
是否设置为有信号?
我不确定为什么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添加了以下重载。输入