15

我是 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() 不会永远阻塞?

4

2 回答 2

9

在这段代码中线程不会正常退出(队列为空时它们确实被阻塞)。程序不会等待它们,因为它们是守护线程

程序不会立即退出,也不会因为q.joinandq.task_done调用而永远阻塞。

每当将项目添加到队列中时,未完成任务的计数就会增加。task_done()每当消费者线程调用以指示该项目已被检索并且所有工作都已完成时,计数就会下降。当未完成任务的计数下降到零时,join()解除阻塞,并且程序存在而不等待守护线程。

于 2013-03-02T11:34:32.890 回答
-3

我曾经也有过一样的问题。当所有线程都完成后,我在进程列表中看到了“睡眠线程”(使用脚本top -H -p <pid><pid>的进程 ID )。ps aux | grep python

我通过将“无限循环”替换while Truewhile 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
于 2014-01-31T12:06:44.290 回答