在线程中“浪费时间”的CPU效率最高的方法是什么?

时间:2011-11-01 19:19:26

标签: multithreading delphi sleep delphi-2006 thread-sleep

我有多个线程(100个),每个线程一次执行几秒钟。当它们执行时,它们花费大量时间等待来自另一个系统(串行设备)的响应。我注意到一次执行100个线程可能是资源占用,所以我实际上限制了任何时候都可以启动的线程数。

虽然在线程中必须有好的和坏的方法来等待外部事件,但它仍然发生在我身上。这种方法是CPU密集型的吗?:

send command ;
repeat
until response arrived ;
process response ;    

这种方法是否会提高效率?:

send command ;
repeat
    Sleep (20) ;
until response arrived ;
process response ;  

*附加信息*

环境是x86 Windows XP。线程代码是与串行设备进行的一系列长时间的交互,但通常,它包括将字符写入COM端口(使用AsyncFree串行库)并等待通过驻留在传入的字符缓冲区上返回字符。他们到达时处理它们。我想这个串行库会让设备读写。线程中的时间可以长达一分钟,也可以短至几秒钟,但大部分时间都花在等待字符离开端口或等待响应字符(波特率很慢),因此我的问题是关于线程在等待时表现的最佳方式。目前我在循环中调用Sleep,等待CharactersInBuffer变为非零,在到达时处理每个字符,并在我有完整响应时退出线程。所以代码看起来更像(忽略超时处理等):

send command ;
Packet = '' ;
repeat

    repeat
        Sleep (20) ;
    until response character arrived ;
    build Packet

until complete packet arrived
process response ;  

3 个答案:

答案 0 :(得分:7)

如果线程真正等待WaitForSingleObject之类的东西,它不使用处理器时间,那么超时,就没有理由在休眠时在线程中加入延迟。

您的用户没有等待线程响应,它没有使用处理器时间,并且其他线程也不会被阻止,因此没有理由让线程进入休眠状态。

正如David Heffernan在评论中指出的那样,如果它现在没有使用100%的CPU,那么就没有问题了。

如果你是单线程的话你可能会使用sleep(),你不得不偶尔在等待串口响应用户之间做出响应。

此外,线程休眠不会使其更有效率。它只会让处理器循环到其他线程。

在一个帖子中看一下sleep(0)作为“浪费时间”的CPU效率方法。

答案 1 :(得分:2)

防止线程使用CPU时间的最有效方法是将其置于“等待模式”。

我根本不使用delphi,但似乎基本原理就在那里。请参阅"Chapter 11. Synchronizers and Events",更具体地说"Event simulation using semaphores"

如果您想在不使用CPU的情况下等待,请使用WaitForEvent

  

检查事件的信号状态。如果它指示事件已发出信号,则发信号通知内部信号量,并减少信号量上阻塞的线程数。然后递增阻塞线程的计数,并对内部信号量执行等待。

如果这与I / O相关,那么事情会有所不同。如果它是一个套接字,那么它可能已经被阻塞,如果它是异步I / O,那么你可以使用信号量和WaitForEvent等等。

在.NET中有Monitor.WaitMonitor.SignalManualResetEventCountDownLatch等,但我不知道delphi中的等价物是什么。

答案 2 :(得分:2)

我不能代表AsyncFree的功能,但一般来说,Windows中的COM端口编程支持重叠I / O,因此您可以使用WaitCommEvent()函数与WaitFor...()函数之一有效地等待数据到达时的通知1}}函数族,例如WaitForSingleObject()。线程可以进入休眠状态,直到通知发出,此时它“唤醒”从端口读取,直到没有任何进一步的读取,然后它可以回到睡眠,直到下一次通知。