如果我设置了3个线程来等待一个互斥量被释放,他们是否根据它们所请求的顺序形成一个队列,或者它是不确定的行为(即我们不知道哪一个会首先拾取它)?
它在SDK文章中明确记录:
如果多个线程正在等待一个互斥锁,则选择一个等待线程。 不要采用先进先出(FIFO)的顺序。 外部事件(如内核模式APC)可以更改等待顺序。
这些事情完全不在你的掌握之中。 所以“未定义的行为”是一个适当的方式来描述它。
互斥对象大多是公平的。 APC案件可能会发生,但并不常见。 特别是如果线程没有做I / O,或者正在使用完成端口或同步进行I / O。
大多数Windows用户模式锁定(SRWLock,CriticalSection)是不公平的,如果你可以在没有阻塞的情况下获取它们,但是如果你不得不在内核中阻塞则是公平的。 这样做的原因是为了避免锁定车队。 当一个公平的锁被争夺的时候,每个获取者都必须在获得锁之前通过调度器和上下文切换路径。 没有人可以“跳过”,只是因为他们碰巧正在跑。 因此,队列中最后一个线程的锁定获取时间增加了队列中每个先前线程的调度和上下文切换时间。 系统不会从这个状态恢复,直到外部负载大部分被移除,因为这是一个稳定的状态。
为了提高性能,我建议使用前面提到的用户模式锁之一,因为它们比内核互斥锁要快得多,如果它们适合你的场景的话。
唤醒顺序不确定,请参阅
单个SetEvent()可以触发多个WaitForSingleObject()
对此似乎有不同的看法,也没有任何明确的信息。 在这个线程中: http : //us.generation-nt.com/answer/are-events-fair-help-38447612.html有些人似乎认为事件的公平性是通过一个简单的FIFO队列实现的,忽略了优先级,而其他人则说不应该假定公平。
底线,我认为你最好不要把自己的逻辑放在公平的基础上,或者用自己的实现来包装一个保证公平的事件。
是的,只有一个线程会被唤醒并锁定互斥锁。 但是订单是不确定的。