Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 现在,为什么监视器需要一个条件变量?_C#_Multithreading_Mutex_Monitor_Condition Variable - Fatal编程技术网

C# 现在,为什么监视器需要一个条件变量?

C# 现在,为什么监视器需要一个条件变量?,c#,multithreading,mutex,monitor,condition-variable,C#,Multithreading,Mutex,Monitor,Condition Variable,当您查看C#的监视器类时,您会发现在它的实现中有一个条件变量和一个互斥体,该类在锁关键字的引擎盖下使用。互斥锁是由一个新线程获取的,如果另一个线程尚未获取互斥锁,那么它将继续检查条件变量,如果它是true,线程可以继续,如果它不是true,那么它将被放在条件变量的线程睡眠队列中,以便在条件变量再次变为真时唤醒 现在,为什么Monitor需要一个条件变量?它检查什么情况?我已经通读了一篇关于监视器的文章,但我还没能推断出它将在什么条件下运行 它不是由lock或Monitor的用户指定的,而是一些内

当您查看C#的
监视器
类时,您会发现在它的实现中有一个条件变量和一个互斥体,该类在
关键字的引擎盖下使用。互斥锁是由一个新线程获取的,如果另一个线程尚未获取互斥锁,那么它将继续检查条件变量,如果它是
true
,线程可以继续,如果它不是true,那么它将被放在条件变量的线程睡眠队列中,以便在条件变量再次变为真时唤醒

现在,为什么
Monitor
需要一个条件变量?它检查什么情况?我已经通读了一篇关于监视器的文章,但我还没能推断出它将在什么条件下运行

它不是由
lock
Monitor
的用户指定的,而是一些内部变量。看到被锁作为参数的
对象
就是锁

这是否就像使用
AutoResetEvent
Mutex
并获取Mutex上的锁,然后查看
AutoResetEvent
是否设置为有信号

我不知道为什么
Monitor
需要一个条件变量,当线程等待获取互斥时,它不也会在释放互斥时被唤醒吗?(操作系统调度程序可能会执行唤醒操作)


我希望这是有意义的,希望有人能在我的理解中找到差距。

这是监视器的过载。请输入CLR 4.0中引入的方法,以更正一个微妙的漏洞

这一点在本文中进行了解释

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

为了避免这种危险,CLR 4.0的设计者在监视器中添加了以下重载


这可能会有一些启示:监视器根本不使用条件变量。也许假装它有一个工具来摸索它的工作方式是有帮助的。但实现方式却大不相同。
Monitor.Enter (_locker);
try
{
  if (_val2 != 0) Console.WriteLine (_val1 / _val2);
  _val2 = 0;
}
finally { Monitor.Exit (_locker); }