我有多个线程(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 ;
答案 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.Wait
,Monitor.Signal
,ManualResetEvent
,CountDownLatch
等,但我不知道delphi中的等价物是什么。
答案 2 :(得分:2)
我不能代表AsyncFree的功能,但一般来说,Windows中的COM端口编程支持重叠I / O,因此您可以使用WaitCommEvent()
函数与WaitFor...()
函数之一有效地等待数据到达时的通知1}}函数族,例如WaitForSingleObject()
。线程可以进入休眠状态,直到通知发出,此时它“唤醒”从端口读取,直到没有任何进一步的读取,然后它可以回到睡眠,直到下一次通知。