如何避免Delphi多线程中的100% CPU占用?

6
我正在创建一个机制,用于在多个服务器之间发送和接收数据。服务器运行在Windows上,使用Delphi 7。
发送数据是由几个同时进行的线程形成的,不可能知道哪个线程将首先形成数据。将数据添加到缓冲区的时刻通过CriticalSection同步。发送线程不断地检查是否有新数据要发送。通过这样做,每个线程会消耗1个CPU核心。这个方法非常快,但是即使服务器没有发送数据,CPU也达到了100%。我需要更多的线程并且需要避免这种高CPU使用率。
我尝试了两种选择:
1.睡眠-如果缓冲区中没有数据,则运行sleep(1)。CPU核心不会被加载,但是对于新数据的反应速度约为100倍。这不是一个解决方案。
2.杀死和创建线程-如果缓冲区中没有数据,则杀死线程。添加数据的函数将创建一个新线程。新线程将发送数据,释放缓冲区,然后再次被杀死。CPU负载降低了,但是创建和杀死需要太多时间。结果速度降低了100倍。
有没有什么替代sleep(1)的方法,既不会消耗100%的CPU又能快速响应?或者是否可以在某个事件发生之前暂停线程?
问题已经得到回答。这对我有效:https://dev59.com/DVLTa4cB1Zd3GeqPbYop#4401519

1
请参考这个链接:https://dev59.com/DVLTa4cB1Zd3GeqPbYop - Ville Krumlinde
2
你尝试过使用OmniThreadLibrary吗?- http://otl.17slon.com/? - RBA
5
不要检查线程,当有任务添加时通知它们。线程可以等待同步对象(例如TEvent)- 当有任务添加到队列中时,您可以获取一个可用的线程并发出信号让它开始工作。如果您不需要重新发明轮子,像OTL这样的库实现了这种类型的东西。 - J...
@VilleKrumlinde 谢谢。这里第一个答案对我有用https://dev59.com/DVLTa4cB1Zd3GeqPbYop#4401519 - Andriy Popov
1个回答

9

你可以使用WaitFor*函数让线程等待数据。这样他们不会占用处理器资源。

我建议使用WaitForMultipleObjects,它可以等待一些事件。例如,主要事件(查找CreateEvent或Delphi包装类TEvent)应该在数据生产者将数据放入缓冲区时设置,另一个事件用于线程终止:

//Execute body
repeat
  WaitRes := WaitForMultipleObjects(2, @FEventHandles, False, CONST_TIMEOUT); // or INFINITE
  if WaitRes = WAIT_OBJECT_0 + 1 then // event from data producer
    GetDataFromBuffer();

until WaitRes = WAIT_OBJECT_0; // external event for thread stop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接