睡在一个事件上

时间:2012-07-31 21:03:56

标签: c windows multithreading

我有一个多线程程序,我无条件地无限期地在一个线程(线程A)中睡眠。当事件发生在另一个线程(线程B)中时,它通过信令唤醒线程A.现在我知道有多种方法可以做到这一点。 当我的程序在Windows环境中运行时,我在Thread-A中使用WaitForSingleObject,在Thread-B中使用SetEvent。它没有任何问题。 我也可以使用基于文件描述符的模型进行轮询,选择。有不止一种方法可以做到这一点。 但是,我试图找到哪种方法最有效。我想在Thread-B信号时唤醒Thread-A asap。你认为什么是最好的选择。 我可以探索基于驱动程序的选项。

由于

1 个答案:

答案 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