【问题标题】:How to avoid 100% CPU in Delphi multithreading?Delphi多线程中如何避免100% CPU?
【发布时间】:2021-04-19 23:13:18
【问题描述】:

我正在创建一种用于在多个服务器上发送和接收数据的机制。服务器在 Windows 上运行,使用 Delphi 7。

发送数据是在几个同时发生的线程中形成的,不可能知道哪个线程首先形成数据。将数据添加到缓冲区的时刻由 CriticalSection 同步。发送线程不断检查是否有任何新数据要发送。通过这样做,每个线程都会吃掉 1 个 CPU 核心。这工作非常快,但即使服务器不发送数据,CPU 也大约为 100%。我需要多个线程,并且需要避免这种高 CPU 使用率。

我尝试了两种选择:

  1. 睡眠 - 如果缓冲区中没有数据,我会运行 sleep(1)。 CPU 内核没有加载,但对新数据的反应速度要慢 100 倍左右。这不是解决方案。

  2. 杀死和创建线程。如果缓冲区中没有数据,我会终止线程。添加数据的函数将创建一个新线程。新线程将发送数据,释放缓冲区并再次被杀死。 CPU 负载减少了,但创建和杀死需要太多时间。结果速度降低了 100 倍。

除了 sleep(1) 之外,是否有任何不消耗 100% CPU 且反应迅速的替代方法?或者是否可以在某些事件发生之前暂停线程?

问题已得到解答。这对我有用https://stackoverflow.com/a/4401519/4052208

【问题讨论】:

  • 您尝试过使用 OmniThreadLibrary - otl.17slon.com 吗?
  • 不要检查您的线程 - 在添加工作时通知他们。线程可以等待像TEvent 这样的同步对象 - 当工作被添加到队列中时,您可以获取一个可用线程并发出信号开始工作。如果你不需要任何特别的东西来重新发明轮子,像 OTL 这样的库就会实现这种类型的东西。
  • @VilleKrumlinde 谢谢。这里的第一个答案对我有用stackoverflow.com/a/4401519/4052208

标签: multithreading delphi asynchronous cpu-usage thread-sleep


【解决方案1】:

您可以使用WaitFor* 函数让线程等待数据。他们不会吃掉处理器资源。

我建议使用WaitForMultipleOjects,它有可能等待一些事件。例如,主事件(查找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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 2011-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多