3

我刚刚从 Red Gate 下载了 ANTS Performance Profiler的试用版,并且正在调查我团队的一些代码。我立即注意到 ANTS 报告有一段特定的代码占用了高达 99% 的 CPU 时间。

我对 ANTS 或一般性能分析完全不熟悉(也就是说,除了使用我确信是非常粗糙和不受欢迎的方法进行自我分析之外double timeToComplete = (endTime - startTime).TotalSeconds),所以我仍在摆弄应用程序和计算出它是如何使用的。但我确实打电话给负责该代码的开发人员,他的直接反应是“是的,它这么说并不让我感到惊讶;但是该代码调用 SignalAndWait [我可以自己看到,感谢 ANTS],它不使用任何 CPU,它只是坐在那里等待要做的事情。” 他建议我简单地忽略该代码并寻找我能找到的任何其他内容。

我的问题:SignalAndWait 是否确实不需要 CPU 开销(如果是,这怎么可能?),性能分析器认为它占用 99% 的 CPU 时间是否合理?我觉得这特别奇怪,因为如果它是 99%,这表明我们的应用程序经常处于空闲状态,不是吗?然而,它的表现最近变得相当低迷。

就像我说的,当谈到这个工具时,我真的只是一个初学者,我对 WaitHandle 类一无所知。因此,任何帮助我了解这里发生的事情的信息都将不胜感激。

4

2 回答 2

1

WaitHandle 确实使您的线程进入睡眠状态。

额外的好处是您可以在这些句柄上设置超时,以便它们可以在一段时间后唤醒。

您还可以从另一个线程(例如,应用程序退出等)向 WaitHandle 发出信号,它们会立即唤醒。

我个人更喜欢具有短超时的 WaitHandle,而不是具有相同超时的 Thread.Sleep,因为当启动 Sleep 时,它必须返回才能恢复操作,而 WaitHandle 可以在需要时立即恢复。

于 2009-06-24T00:13:50.080 回答
0

我认为您的代码中可能存在严重错误。EventWaitHandle 有 2 种语义,具体取决于其重置模式。当 EventWaitHandle 处于 AutoReset 模式时,所有等待线程都被阻塞,直到事件发出信号,一旦事件发出信号,后续的等待操作将重置其状态,并再次调用等待阻塞的线程。

但是,如果 EventWaitHandle 处于 ManualReset 模式,它将一直保持信号状态,直到您对其手动调用 Reset,这意味着如果 EventWaitHandle 信号信号并且线程在紧密循环中对其调用等待,则该线程将不会阻塞,直到 Reset在事件上手动调用,所以考虑这个假设场景

EventWaitHandle h1, h2;
h1 = new EventWaitHandle(true, EventWaitHandle.ManualReset); // the event is already signaled.
h2 = new EventWaitHandle(false, EventWaitHandle.ManualReset);
while(true)
{
  WaitHandle.SignalAndWait(h2,h1);
}

上面的循环将占用您的大部分 CPU,直到其他一些线程调用 h1.Reset(),这将使 SignalAndWait 阻塞。

希望这可以帮助。

有关更多信息,请查看 http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx

于 2009-06-24T05:24:22.837 回答