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的线程。输出和循环,一直运行到self。完成是正确的(或者达到最大执行时间)。
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
5 个解决方案
#1
11
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。这里的输出,主要任务是消耗它们吗?如果是的话,这是为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)
您的生产线程将条目添加到队列中。put(项)
[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(例如,在设置标志之前,可以将多个项附加到队列中,从而导致代码在第一个队列中被释放)。更新一个建议从ΤΖΩΤΖΙΟΥ——生产者线程应该添加一个特殊标记(完成)队列,以指示它是完整的。
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.
注意:如果您有多个生产线程,您将需要一个更通用的方法来检测它们何时全部完成。您可以使用相同的策略来实现这一点——每个线程都有一个完成的标记,当使用者看到num_threads标记时就会终止。
#2
1
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。在工人中,做一些类似自我的事情。done =在工作开始时使用thread . semaphore(),完成后使用self.done.release()。在上面所提到的代码中,而不是繁忙的循环,只做self。当工作线程完成时,控件将返回。
Edit: I'm afraid I don't address your needed timeout value, though; this issue describes the need for a semaphore timeout in the standard library.
编辑:恐怕我没有说明您需要的超时值;这个问题描述了在标准库中需要信号量超时。
#3
0
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(秒)在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
#4
0
use mutex module or event/semaphore
使用互斥模块或事件/信号量
#5
0
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.
我没有发布一个示例,因为我从未使用过事件对象,而且替代方法可能不那么简单。
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时间。
#1
11
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。这里的输出,主要任务是消耗它们吗?如果是的话,这是为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)
您的生产线程将条目添加到队列中。put(项)
[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(例如,在设置标志之前,可以将多个项附加到队列中,从而导致代码在第一个队列中被释放)。更新一个建议从ΤΖΩΤΖΙΟΥ——生产者线程应该添加一个特殊标记(完成)队列,以指示它是完整的。
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.
注意:如果您有多个生产线程,您将需要一个更通用的方法来检测它们何时全部完成。您可以使用相同的策略来实现这一点——每个线程都有一个完成的标记,当使用者看到num_threads标记时就会终止。
#2
1
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。在工人中,做一些类似自我的事情。done =在工作开始时使用thread . semaphore(),完成后使用self.done.release()。在上面所提到的代码中,而不是繁忙的循环,只做self。当工作线程完成时,控件将返回。
Edit: I'm afraid I don't address your needed timeout value, though; this issue describes the need for a semaphore timeout in the standard library.
编辑:恐怕我没有说明您需要的超时值;这个问题描述了在标准库中需要信号量超时。
#3
0
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(秒)在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
#4
0
use mutex module or event/semaphore
使用互斥模块或事件/信号量
#5
0
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.
我没有发布一个示例,因为我从未使用过事件对象,而且替代方法可能不那么简单。
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时间。