在 Windows 上根据给定优先级获取互斥锁
Posted
技术标签:
【中文标题】在 Windows 上根据给定优先级获取互斥锁【英文标题】:Acquiring mutex based on given priority on Windows 【发布时间】:2019-04-02 13:01:40 【问题描述】:我有几个需要通信的进程,我希望能够只让一个进程同时与另一个通信,例如,如果我有进程 A、B、C、D。如果 B 想要发送给 A 发消息,C 不能发消息,甚至 D 也发不出去。
我已经有了通信所需的管道,并且我正在 WinAPI 中寻找一个对象来实现排他性行为。
我还需要设置一个优先级,所以假设 C 正在向 D 发送一条消息,并且 A 和 B 都想发送,当 C 完成后,我需要能够确保 A 总是先发送。
我知道,这听起来像是一种会导致饥饿的情况,事实上它会,但我正在尝试模拟一个遭受饥饿 (CANbus) 的真实设置。
知道我可以使用哪种对象吗?
【问题讨论】:
目的并不是真正模拟饥饿,而是模拟几个处理器通过 CAN 通信,使用多个进程通过管道通信。在模拟中。我缺乏交流的排他性。 @AlexF 虽然肯定更简单,但我更愿意寻找不涉及外部进程的解决方案。 排他性很容易获得,只需要一个命名的互斥体。优先级,不,一点也不。在这种情况下需要一个专门的仲裁进程是很常见的,主要是为了使整个系统能够适应意外故障。在模拟中您不关心它,但在您的 CANbus 模拟中它扮演总线的角色。使用线程而不是进程让这一切变得更容易。 @HansPassant 仲裁程序会简化事情吗?它会如何表现?我宁愿不需要一个,但如果没有其他(足够简单的)解决方案存在,添加另一个进程是可行的。 这不是简化,而是要求。只有仲裁者可以对消息进行排序以赋予优先级,它充当“总机”。 【参考方案1】:与所有其他现代操作系统一样,Windows 将根据优先级调度线程。如果您有不同优先级的线程,并且它们都在等待同一个互斥信号量,那么当该互斥量下一次可用时,将运行最高优先级的线程。
因此,您应该能够设置线程优先级,使 A 高于 B,并拥有一个互斥信号量,它们都在通信之前获取,并在完成后释放。因此,当 C 完成与 D 的通信后,它将释放互斥体,并且在两个就绪线程(A 和 B)中,Windows 将在 B 之前调度 A。由于 A 将获取信号量,因此 B 将在 A 完成之前变为未就绪状态并释放了互斥锁。
【讨论】:
这肯定是我考虑过的事情,但我也听说优先级不是规则,而是对调度程序的建议(它可能不尊重为避免挨饿而设置的优先级),我需要一些东西这是确定性的。此外,更改优先级可能会影响执行的其余部分,这应该像完全独立一样完成。 @bracco23 不,它们是规则。当然在内核调度程序必须做出决定的时候——例如。两个线程在同一个信号量上等待,并且它刚刚被另一个释放 - 这就是它必须注意两个线程的优先级的地方。如果没有,那么调度程序将忽略线程优先级,这有什么意义。与 *nixes 使用的简单方案相比,Windows 中线程和进程优先级的工作方式不同,但它的调度行为是确定性的。 @bracco23,我怀疑对我的答案投反对票的人实际上并没有费心阅读 Windows Internals 的第 5 章,该章规定了规则。 Windows 确实会处理进程优先级,但进程中未调度线程的相对优先级不受此影响。除了根据是否有鼠标焦点动态改变进程优先级之外,Windows 的调度程序是一个优先级驱动的抢占系统,就像其他任何东西一样。它不会做(Linux 也不会)是解决优先级倒置 - 但这不是您要询问的问题以上是关于在 Windows 上根据给定优先级获取互斥锁的主要内容,如果未能解决你的问题,请参考以下文章