Python - 线程与无限循环
我有一个线程,它会把行添加到 self.output 里,还有一个循环会一直运行,直到 self.done 变成 True(或者达到最大执行时间)。
除了使用一个不断检查是否完成的 while 循环,还有没有更有效的方法?因为这个 while 循环在运行的时候会让 CPU 升到 100%。
time.clock()
while True:
if len(self.output):
yield self.output.pop(0)
elif self.done or 15 < time.clock():
if 15 < time.clock():
yield "Maximum Execution Time Exceeded %s seconds" % time.clock()
break
5 个回答
0
使用互斥锁模块或者事件/信号量。
1
使用信号量;让工作线程在完成后释放它,并让你的添加线程在工作线程完成之前保持阻塞状态。
也就是说,在工作线程中,开始工作时可以写类似 self.done = threading.Semaphore()
的代码,完成时则用 self.done.release()
。在你提到的代码中,别用忙等的方式,直接用 self.done.acquire()
;当工作线程完成后,控制权就会返回。
补充:我担心我没有解决你需要的超时值;这个 问题 描述了标准库中信号量超时的需求。
11
你的线程是在往self.output里添加内容吗?而主任务又在消费这些内容吗?如果是这样的话,这正好适合用队列(Queue.Queue)来处理。你的代码可以改成这样:
import Queue
# Initialise queue as:
queue = Queue.Queue()
Finished = object() # Unique marker the producer will put in the queue when finished
# Consumer:
try:
while True:
next_item = self.queue.get(timeout=15)
if next_item is Finished: break
yield next_item
except Queue.Empty:
print "Timeout exceeded"
你的生产者线程可以用queue.put(item)
把项目添加到队列里。
[编辑] 原来的代码在检查self.done的时候有个竞争问题(比如在标志设置之前,可能会有多个项目被添加到队列,这样代码会在第一个项目时就退出)。更新后,建议生产者线程在队列里添加一个特殊的标记(Finished),来表示它已经完成。
注意:如果你有多个生产者线程,你需要一种更通用的方法来检测它们是否都完成。你可以用同样的策略——每个线程添加一个Finished标记,消费者在看到num_threads个标记时就结束。