Python 线程和队列示例
我刚开始学习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()不会一直卡在那儿呢?
2 个回答
-3
我也遇到过同样的问题。当所有线程都完成后,我在进程列表中看到有“睡眠线程”(可以用 top -H -p <pid>
命令查看,其中 <pid>
是通过 ps aux | grep python
找到的你的脚本的进程ID)。
我通过把“无限循环”的 while True
改成 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
9
在这段代码中,线程并不会正常退出(当队列为空时,它们确实会被阻塞)。程序不会等待这些线程,因为它们是守护线程。
程序不会立刻退出,也不会一直卡住,这要归功于q.join
和q.task_done
的调用。
每当有新任务加入队列时,未完成任务的数量就会增加。当消费者线程调用task_done()
来表示这个任务已经完成时,未完成任务的数量就会减少。当未完成任务的数量降到零时,join()
就会解除阻塞,程序就会退出,而不需要等待守护线程。