我有一个多线程程序,其中我无条件地在一个线程(线程A)中 sleep 无限时间。当另一个线程(线程 B)中发生事件时,它会通过信号唤醒线程 A。现在我知道有多种方法可以做到这一点。 当我的程序在Windows环境中运行时,我在线程A中使用WaitForSingleObject,在线程B中使用SetEvent。它工作正常,没有任何问题。 我还可以使用基于文件描述符的模型进行轮询、选择。有不止一种方法可以做到这一点。 但是,我正在尝试找到最有效的方法。我想每当线程 B 发出信号时尽快唤醒线程 A。您认为最好的选择是什么。 我可以探索基于驱动程序的选项。
谢谢
最佳答案
如上所述,在线程 B 中触发 SetEvent
并在线程 A 中触发 WaitForSingleObject
速度很快。
但是必须考虑一些条件:
单核/处理器:正如 Martin 所说,等待线程将抢占信号线程。使用这样的方案,您应该注意信号线程 (B) 在
SetEvent
之后立即进入空闲状态。例如,这可以通过sleep(0)
来完成。多核/处理器:人们可能认为将两个线程放在不同的核/处理器上有好处,但这实际上并不是一个好主意。如果两个线程位于同一核心/处理器上,则调用
SetEvent
和返回WaitForSingleObject
之间的时间间隔会短得多。处理一个核心上的两个线程 ( SetThreadAffinityMask ) 还允许通过其优先级设置 ( SetThreadPriority ) 来处理它们的行为。您可以以更高的优先级运行等待线程,或者必须确保信号线程在设置事件后实际上没有执行任何操作。
您必须处理其他一些同步问题:下一个事件何时发生?线程 A 是否已完成其任务?最有效的第二个事件可以用来解决这个问题:当线程A完成时,它设置一个事件以指示允许线程B再次设置其事件。线程B实际上会先设置事件,然后等待反馈事件,满足立即空闲的要求。
如果您希望允许线程 B 在线程 A 尚未完成且尚未处于等待状态时设置事件,则应考虑使用信号量而不是事件。这样,线程 B 的“调用/事件”数量将被保留,并且线程 A 中的等待函数可以跟进,因为它返回的是信号量已释放的次数。信号量对象与事件一样快。
摘要:
通过
SetThreadAffinityMask
让两个线程位于同一核心/CPU 上。通过另一个事件扩展
SetEvent
/WaitForSingleObject
以建立握手
。根据处理的详细信息,您还可以考虑 semaphore objects .
关于c - 参加事件时 sleep ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11748979/