2

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

谢谢

4

1 回答 1

2

如前所述,触发SetEvent线程 BWaitForSingleObject中的一个和线程 A 中的一个很快。但是必须考虑一些条件:

  • 单核/处理器:正如 Martin 所说,等待线程将抢占信号线程。使用这样的方案,您应该注意信号线程 (B) 在SetEvent. 这可以通过一个sleep(0)例子来完成。

  • 多核/处理器:人们可能认为将两个线程放在不同的核/处理器上会有好处,但这并不是一个好主意。如果两个线程都在同一个核心/处理器上,调用SetEvent和返回之间的时间跨度WaitForSingleObject会更短。

  • 在一个内核上处理两个线程 ( SetThreadAffinityMask ) 还允许通过它们的优先级设置 ( SetThreadPriority ) 来处理它们的行为。您可以以更高的优先级运行等待线程,或者您必须确保信号线程在设置事件后确实没有做任何事情。

  • 您必须处理其他一些同步问题:下一个事件何时发生?线程 A 会完成它的任务吗?最有效的第二个事件可以用来解决这个问题:当线程 A 完成时,它设置一个事件以指示允许线程 B 再次设置它的事件。线程 B 将有效地先设置事件然后等待反馈事件,它满足立即进入空闲状态的要求。

  • 如果您想允许线程 B 设置事件,即使线程 A 尚未完成且尚未处于等待状态,您应该考虑使用信号量而不是事件。这样,来自线程 B 的“调用/事件”的数量得以保留,线程 A 中的等待函数可以跟进,因为它返回的信号量已被释放的次数。信号量对象与事件一样快。

概括:

  • 通过SetThreadAffinityMask.

  • 通过另一个事件扩展SetEvent/WaitForSingleObject以建立Handshake.

  • 根据处理的细节,您还可以考虑信号量对象

于 2012-08-01T13:41:46.940 回答