被互斥锁阻塞的等待线程执行顺序

5

我有一个互斥锁来控制多个线程对单个对象的访问。当一个线程完成后,互斥锁被解锁,以允许其他线程操作该对象。在Windows上使用WaitForSingleObject函数时,线程的信号顺序是有序的吗?我希望第一个尝试锁定互斥锁的线程现在能够锁定互斥锁。这将是一个先进先出(FIFO)队列,以使对被阻塞线程的信号不是随机发生的。我需要实现自己的排队机制来实现这一点吗?如果需要,哪些函数是有用的?


1
为什么要迫使最低效的行为呢?如果你有三个孩子,每个孩子都想借车去做三件事情,那么最有效的方法很可能不是让每个孩子做一件事情然后归还车辆。 - David Schwartz
4个回答

8

FIFO信号传递会导致锁队列问题。在较新版本的Win32 API中,通过将互斥体和其他同步原语显式不公平(即无FIFO)来解决队列问题。

如果有多个线程正在等待互斥体,则会选择一个等待线程。不要假设先进先出(FIFO)顺序。诸如内核模式APC之类的外部事件可以改变等待顺序。


你说得很对,FIFO并没有被明确保证。然而,也有一个保证,即饥饿仍将被避免。 - Steven Sudit
@Steven:对的。据我所知,队列头部会定期移动到尾部,这可以确保没有无限饥饿。线程仍然可能遇到临时饥饿。 - Remus Rusanu

0

如果你想要一个FIFO队列,那么你需要实现自己的排队机制。


0
如果您希望解锁按照FIFO顺序进行,可以使用自定义锁。ACE中存在一个FIFO锁,称为ACE_Token,由于它是开源的,因此您可以将其用作参考实现。我认为使用它的开销将是最小的。

0

实现自己的调度程序在 Windows 上可以使用纤程(Fibers)的方式。主线程将等待互斥量,一旦返回,您需要在一个线程安全的队列中显式地调用 SwitchToFiber。

  1. 调用 SwitchToFiber 的线程需要先调用 ConvertThreadToFiber。
  2. 在 SwitchToFiber 函数中,应该从队列中调用 SwitchToFiber。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接