【问题标题】:Now, why does Monitor need a condition variable?现在,为什么 Monitor 需要条件变量?
【发布时间】:2014-08-24 10:45:50
【问题描述】:

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

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

它不是lockMonitor的用户指定的东西,而是一些内部变量。看到object被锁作为参数,就是supposedly only for identifying锁。

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

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

我希望这是有道理的,并且希望有人能找到我理解中的差距。

【问题讨论】:

标签: c# multithreading mutex monitor condition-variable


【解决方案1】:

这是 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 中添加了以下重载

【讨论】:

    猜你喜欢
    • 2020-09-07
    • 2021-03-21
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    相关资源
    最近更新 更多