繁体   English   中英

Python - 线程和一个真正的循环

[英]Python - Threading and a While True Loop

我有一个线程,将行追加到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

你的线程是否附加到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标记时终止。

使用信号量; 让工作线程在完成后释放它,并阻止你的追加线程直到工人完成信号量。

即。 在worker中,在工作开始时执行self.done = threading.Semaphore() ,完成后执行self.done.release() 在上面提到的代码中,只需执行self.done.acquire() ;而不是busy循环。 当工作线程完成时,控制权将返回。

编辑:我担心我没有解决你所需的超时值; 问题描述了标准库中信号量超时的必要性。

使用time.sleep(seconds)在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

您必须在此处使用同步原语。 请看这里: http//docs.python.org/library/threading.html

事件对象看起来很简单,应该可以解决您的问题。 您还可以使用条件对象或信号量。

我没有发布一个例子,因为我从未使用过Event对象,而且替代方案可能不那么简单。


编辑:我不确定我理解你的问题。 如果线程可以等到某个条件得到满足,则使用同步。 否则,有人发布的sleep()解决方案会占用太多的CPU时间。

使用互斥模块或事件/信号量

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM