Python 线程和队列示例

15 投票
2 回答
23066 浏览
提问于 2025-04-17 17:41

我刚开始学习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.joinq.task_done的调用。

每当有新任务加入队列时,未完成任务的数量就会增加。当消费者线程调用task_done()来表示这个任务已经完成时,未完成任务的数量就会减少。当未完成任务的数量降到零时,join()就会解除阻塞,程序就会退出,而不需要等待守护线程。

撰写回答