Python线程和While-True循环

2024-05-14 21:47:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个将行追加到self.output的线程和一个运行到self.done为True(或达到最大执行时间)的循环。

有没有比使用while循环更有效的方法来实现这一点,而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

Tags: 方法selftrueoutputleniftime时间
3条回答

使用信号量;让工作线程在完成时释放它,并阻止附加线程,直到工作线程完成信号量。

也就是说,在工作者中,在工作开始时做一些类似于self.done = threading.Semaphore()的事情,在工作结束时做一些类似于self.done.release()的事情。在上面提到的代码中,不要使用busy循环,只需执行self.done.acquire();当工作线程完成时,控件将返回。

编辑:恐怕我没有说明您需要的超时值;这个issue描述了在标准库中需要信号量超时。

使用time.sleep(秒)在while循环的每次迭代后创建一个短暂的暂停以放弃cpu。在每次迭代过程中,您必须根据任务完成后快速捕获任务的重要性来设置睡眠时间。

示例:

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

    time.sleep(0.01) # sleep for 10 milliseconds

您的线程是否在这里附加到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),以表明它是完整的。

注意:如果有多个生产者线程,则需要一种更通用的方法来检测它们何时全部完成。您可以使用相同的策略来实现这一点—每个线程都有一个完成的标记,当使用者看到num_threads标记时,它就会终止。

相关问题 更多 >

    热门问题