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