事件响应比信号量快



在一个项目中,我遇到了这样的情况(在windows 7上),

当几个线程繁忙时(我所有的CPU核心都忙于工作),一个线程会有延迟以接收信号量(信号量从0增加到1)。它可能长达1.5ms。

我通过缓存一些小东西并提前增加信号量值来解决这个问题。

因此,对我来说,信号量的信号传递似乎很慢,线程不会立即接收到信号量(尤其是在CPU繁忙的时候),但如果你在某个线程开始等待信号量之前提前发出信号,就不会有延迟。

我曾经认为事件只是一个最大值为1的信号量,,现在遇到这种情况,我开始怀疑事件在注意线程"唤醒"方面是否比信号量更快。

对不起,我试过了,但没有演示出来,我还不太擅长线程。

编辑:在Windows上,Event确实比Semaphore快吗?

1.5毫秒并不能仅仅用不同多线程原语之间的开销来解释。

为了简化,线程有三种状态

  • 被阻止
  • 可运行的
  • 正在运行

如果线程正在等待信号量或事件,那么它就会被阻塞。当事件发出信号时,它将变为可运行。

因此,真正的问题是,"一个可运行的线程什么时候真正运行?"这取决于调度程序算法等,但显然它需要在一个核心上运行,这意味着其他任何东西都不能同时在该核心上"运行"。当以下情况之一发生时,调度程序通常会从核心中"删除"当前正在运行的线程

  • 它等待信号量/事件,因此变为"阻塞">
  • 它已经连续运行了一段时间(基于时间或循环调度)
  • 优先级更高的线程可以运行

1.5毫秒可能是循环调度或基于时间的调度。你的线程可以运行,但还没有启动。如果线程必须启动,并且应该引导出当前线程,那么您可以尝试通过SetThreadPriority增加它的优先级

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686277(v=vs.85).aspx

如果一个线程正在等待一个信号量,并且它得到了信号,那么在我的有限测试中,该线程将在一个没有过载的盒子上运行约10us。

如果

发出信号的线程在另一个进程中,而不是任何线程被抢占。

运行发出信号的线程需要在另一个核心上运行的线程被抢占。

该框已被优先级较高的线程重载。

1.5毫秒一定是一个极端的情况,你的盒子非常繁忙。

在这种情况下,用事件替换信号量不太可能导致总体信令延迟的任何显著改善,因为线程间信令所需的大部分工作/延迟与调度/调度有关,这在任何一种情况下都是必需的。

最新更新