WaitForSingleObject - 将等待的线程从队列中解脱出来

WaitForSingleObject - do threads waiting form a queue?

本文关键字:队列 解脱 脱出 线程 等待 WaitForSingleObject      更新时间:2023-10-16

如果我设置 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 队列来实现事件的公平性,而其他人则说不应该假设公平性。

底线,我认为你最好不要将你的逻辑建立在公平的基础上,或者用你自己的实现来包装一个事件,以保证公平。

是的,只有一个线程会被唤醒并锁定互斥锁。但秩序是不确定的。