【问题标题】:Monitor.TryEnter()Monitor.TryEnter()
【发布时间】:2012-02-14 14:10:12
【问题描述】:

我想知道监视器类。 据我所知,所有等待线程都不是 FIFO。 第一个获得锁的人并不总是等待队列中的第一个。 它是否正确? 有什么办法可以保证FIFO条件吗?

问候

【问题讨论】:

  • 好问题。你读过这个吗? stackoverflow.com/questions/5111779/…
  • 为什么fifo很重要?因为你不能真正保证线程到达的顺序。此外,对于异步调用过程 (APC),您甚至无法保证在返回等待锁之前不会暂时借用等待线程来服务回调。
  • @ChrisChilvers FIFO 很重要!以至于微软现在引入了保证 FIFO 行为的锁。
  • @adelphus 我同意。你能指出哪些锁可以保证 FIFO 行为吗??
  • 恐怕不在 .NET 中。我所说的锁处于内核模式:msdn.microsoft.com/en-us/library/windows/hardware/…

标签: c# .net multithreading .net-4.0


【解决方案1】:

如果您指的是内置方式,那么不是。在一个循环中反复调用TryEnter 根据定义是不公平的,不幸的是简单的Monitor.Enter 也不是。从技术上讲,线程可以永远等待而不会获得锁。

如果您想要绝对公平,您需要自己实现它,使用队列来跟踪到达顺序。

【讨论】:

    【解决方案2】:

    有什么办法可以保证先进先出条件吗?

    一句话:不!

    我为此写了一篇短文:Is the Ready Queue FIFO?

    【讨论】:

      【解决方案3】:

      看看这个问题,我觉得对你很有用-Does lock() guarantee acquired in order requested?

      尤其是这句话:

      因为监视器在内部使用内核对象,所以它们表现出相同的 操作系统同步机制的大致 FIFO 行为 展览(在前一章中描述)。监视器是不公平的,所以 如果另一个线程在唤醒等待之前尝试获取锁 线程尝试获取锁,允许偷偷摸摸的线程 获取锁。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-23
        • 1970-01-01
        • 1970-01-01
        • 2011-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多