【问题标题】:Why is this queue.join call blocking indefinitely?为什么这个 queue.join 调用会无限期地阻塞?
【发布时间】:2019-05-12 13:59:35
【问题描述】:

我正在使用 python3.6 中的个人项目,我遇到了以下问题,导致 my_queue.join() 调用无限期阻塞。请注意,这不是我的实际代码,而是演示问题的最小示例。

import threading
import queue

def foo(stop_event, my_queue):
  while not stop_event.is_set():
    try:
      item = my_queue.get(timeout=0.1)
      print(item) #Actual logic goes here
    except queue.Empty:
      pass
  print('DONE')

stop_event = threading.Event()
my_queue = queue.Queue()
thread = threading.Thread(target=foo, args=(stop_event, my_queue))
thread.start()

my_queue.put(1)
my_queue.put(2)
my_queue.put(3)

print('ALL PUT')

my_queue.join()

print('ALL PROCESSED')

stop_event.set()

print('ALL COMPLETE')

我得到以下输出(实际上一直是一致的,但我知道输出顺序可能因线程而异):

ALL PUT
1
2
3

无论我等待多长时间,我都不会看到ALL PROCESSED 输出到控制台,那么为什么my_queue.join() 在处理完所有项目后会无限期地阻塞?

【问题讨论】:

    标签: python-3.x queue python-multithreading


    【解决方案1】:

    来自docs

    每当一个项目被添加到 队列。 每当消费者线程调用时计数就会减少 task_done() 表示该项目已被检索并对其进行所有工作 完成。当未完成任务的计数降至零时,join() 解锁。

    您永远不会在 foo 函数中调用 q.task_done()foo 函数应该类似于示例:

    def worker():
        while True:
            item = q.get()
            if item is None:
                break
            do_work(item)
            q.task_done()
    

    【讨论】:

    • 完美,这正是我所缺少的,自从我使用多线程 python 已经有一段时间了,我完全忘记了。
    猜你喜欢
    • 2011-10-16
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多