我是python的新手(我来自PHP),我一直在阅读教程和尝试几天,但我无法理解这个队列示例(http://docs.python.org/2/library/queue.html)
def worker():
while True:
item = q.get()
do_work(item)
q.task_done()
q = Queue()
for i in range(num_worker_threads):
t = Thread(target=worker)
t.daemon = True
t.start()
for item in source():
q.put(item)
q.join() # block until all tasks are done
我不明白的是工作线程如何完成和存在。我已经读过q.get()块直到一个项目可用,所以如果所有项目都被处理并且队列中没有任何项目,为什么q.get()不会永远阻止?
答案 0 :(得分:9)
在此代码中,线程不会正常退出(当队列为空时,它们确实被阻止)。该程序不会等待它们,因为它们是daemon threads。
由于q.join
和q.task_done
来电,该计划不会立即退出,也不会永久阻止。
每当项目添加到队列时,未完成任务的数量就会增加。每当消费者线程调用task_done()
以指示该项目已被检索并且其上的所有工作都已完成时,计数就会下降。当未完成任务的数量降至零时,join()
取消阻塞,并且程序存在而不等待守护程序线程。
答案 1 :(得分:-3)
我遇到了同样的问题。完成所有线程后,我在进程列表中看到“正在运行的线程”(使用top -H -p <pid>
<pid>
,ps aux | grep python
是您的脚本的while True
进程ID。
我通过将“无限循环”while not q.empty():
替换为def worker():
while not q.empty():
item = q.get()
do_work(item)
q.task_done()
q = Queue()
for i in range(num_worker_threads):
t = Thread(target=worker)
t.daemon = True
t.start()
for item in source():
q.put(item)
q.join() # block until all tasks are done
解决了这个问题。
它解决了“睡眠线程”的问题。
{{1}}