我有一个多线程程序,我无条件地无限期地在一个线程(线程A)中睡眠。当事件发生在另一个线程(线程B)中时,它通过信令唤醒线程A.现在我知道有多种方法可以做到这一点。 当我的程序在Windows环境中运行时,我在Thread-A中使用WaitForSingleObject,在Thread-B中使用SetEvent。它没有任何问题。 我也可以使用基于文件描述符的模型进行轮询,选择。有不止一种方法可以做到这一点。 但是,我试图找到哪种方法最有效。我想在Thread-B信号时唤醒Thread-A asap。你认为什么是最好的选择。 我可以探索基于驱动程序的选项。
由于
答案 0 :(得分:2)
如上所述,在线程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
扩展为另一个事件以建立Handshake
。
根据处理的详细信息,您还可以考虑semaphore objects。