Python - 线程和 While 真循环
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/808746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python - Threading and a While True Loop
提问by Ian
I have a thread that appends rows to self.output and a loop that runs until self.done is True (or the max execution time is reached).
我有一个线程将行附加到 self.output 和一个循环,直到 self.done 为 True (或达到最大执行时间)。
Is there a more efficient way to do this other than using a while loop that constantly checks to see if it's done. The while loop causes the CPU to spike to 100% while it's running..
除了使用不断检查是否完成的 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
回答by Brian
Are your threads appending to self.output here, with your main task consuming them? If so, this is a tailor-made job for Queue.Queue. Your code should become something like:
您的线程是否附加到 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"
Your producer threads add items to the queue with queue.put(item)
您的生产者线程将项目添加到队列中 queue.put(item)
[Edit]The original code has a race issue when checking self.done (for example multiple items may be appended to the queue before the flag is set, causing the code to bail out at the first one). Updated with a suggestion from ΤΖΩΤΖΙΟΥ - the producer thread should instead append a special token (Finished) to the queue to indicate it is complete.
[编辑]原始代码在检查 self.done 时存在竞争问题(例如,可能会在设置标志之前将多个项目附加到队列中,从而导致代码在第一个时退出)。更新了来自 ΤΖΩΤΖΙΟΥ 的建议 - 生产者线程应该将一个特殊的标记 (Finished) 附加到队列中以指示它已完成。
Note: If you have multiple producer threads, you'll need a more general approach to detecting when they're all finished. You could accomplish this with the same strategy - each thread a Finished marker and the consumer terminates when it sees num_threads markers.
注意:如果您有多个生产者线程,您将需要一种更通用的方法来检测它们何时全部完成。您可以使用相同的策略来实现这一点——每个线程都有一个 Finished 标记,消费者在看到 num_threads 标记时终止。
回答by esm
Use a semaphore; have the working thread release it when it's finished, and block your appending thread until the worker is finished with the semaphore.
使用信号量;让工作线程在完成后释放它,并阻止您的附加线程,直到工作线程完成信号量。
ie. in the worker, do something like self.done = threading.Semaphore()
at the beginning of work, and self.done.release()
when finished. In the code you noted above, instead of the busy loop, simply do self.done.acquire()
; when the worker thread is finished, control will return.
IE。在工人中,self.done = threading.Semaphore()
在工作开始时和self.done.release()
完成时做一些事情。在您上面提到的代码中,不要使用忙循环,只需执行self.done.acquire()
; 当工作线程完成时,控制将返回。
Edit: I'm afraid I don't address your needed timeout value, though; this issuedescribes the need for a semaphore timeout in the standard library.
编辑:不过,恐怕我没有解决您需要的超时值;这个问题描述了标准库中信号量超时的需要。
回答by moinudin
Use time.sleep(seconds) to create a brief pause after each iteration of the while loop to relinquish the cpu. You will have to set the time you sleep during each iteration based on how important it is that you catch the job quickly after it's complete.
使用 time.sleep(seconds) 在 while 循环的每次迭代后创建一个短暂的暂停以放弃 CPU。您必须根据在完成工作后快速完成工作的重要性来设置每次迭代期间的睡眠时间。
Example:
例子:
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
回答by Bastien Léonard
You have to use a synchronization primitive here. Look here: http://docs.python.org/library/threading.html.
您必须在此处使用同步原语。看这里:http: //docs.python.org/library/threading.html。
Event objects seem very simple and should solve your problem. You can also use a condition object or a semaphore.
事件对象看起来很简单,应该可以解决您的问题。您还可以使用条件对象或信号量。
I don't post an example because I've never used Event objects, and the alternatives are probably less simple.
我没有发布示例,因为我从未使用过 Event 对象,而且替代方案可能不那么简单。
Edit:I'm not really sure I understood your problem. If a thread can wait until some condition is statisfied, use synchronization. Otherwise the sleep()
solution that someone posted will about taking too much CPU time.
编辑:我不确定我是否理解您的问题。如果线程可以等到某个条件满足,则使用同步。否则sleep()
,有人发布的解决方案将占用太多 CPU 时间。
回答by Francis
use mutex module or event/semaphore
使用互斥模块或事件/信号量