在Python中,什么';这是在队列处于';s不是空的,并且总是调用task_done?

在Python中,什么';这是在队列处于';s不是空的,并且总是调用task_done?,python,multithreading,queue,Python,Multithreading,Queue,我刚刚遇到过这样一种情况:我编写的一个多线程应用程序在与另一个线程中的一个队列交互时挂起,该队列由一个库填充 简单地说,我只是在做 while not q.empty(): row = q.get() # do something with row 我这样做的原因(特别是不包括task\u done)是因为我对多线程或python中的Queue没有太多的经验,这就是示例代码中的内容 在我的情况下,在运行数小时后的某个时间点,应用程序会挂起,有时挂在q.empty(),有时挂在q

我刚刚遇到过这样一种情况:我编写的一个多线程应用程序在与另一个线程中的一个队列交互时挂起,该队列由一个库填充

简单地说,我只是在做

while not q.empty():
    row = q.get()
    # do something with row
我这样做的原因(特别是不包括
task\u done
)是因为我对多线程或python中的
Queue
没有太多的经验,这就是示例代码中的内容

在我的情况下,在运行数小时后的某个时间点,应用程序会挂起,有时挂在
q.empty()
,有时挂在
q.get()
,有时挂在
q.get()
之后

当我读到其他有类似问题的人时,我才了解到任务完成的情况,当我把它添加到我的代码中时,就像

while not q.empty():
    row = q.get()
    # do something with row
    q.task_done()

我经历的这些绞刑已经停止了。我在整个应用程序中执行了一些类似的排队操作,我想要一种标准化的方法来处理在q
中运行而不是q.empty()
,使用
q.get()
获取一行,并调用
q.task\u done()
这是我最喜欢的方法,我现在使用的是a的组合来处理
get
task\u done
之类的

class read_from_q:
    def __init__(self, q, block=False, timeout=None):
        """
         :param Queue.Queue q:
         :param bool block:
         :param timeout:
        """
        self.q = q
        self.block = block
        self.timeout = timeout

    def __enter__(self):
        return self.q.get(self.block, self.timeout)

    def __exit__(self, _type, _value, _traceback):
        self.q.task_done()
结合a来处理
not empty()
检查,并
行返回给您

def queue_rows(q, block=False, timeout=None):
    """
     :param Queue.Queue q:
     :param bool block:
     :param int timeout:
    """
    while not q.empty():
        with read_from_q(q, block, timeout) as row:
            yield row
所以现在,不是写作

while not q.empty():
    row = q.get()
    # do something with row
    q.task_done()
我用

for row in queue_rows(q):
    # do something with row and fogedaboutit

我个人认为更优雅,更安全(因为我不会忘记调用以前的代码< Taskydo-/Cuth>)。

确保使用同步队列。get()将使用默认(block=True,timeout=None)参数,因此听起来您可能在其他地方遇到了死锁。对应的put()应该是什么?我没有权限访问它,因为它在库中(虽然我可以请求对它进行更新,或者传递我自己的队列子类,并在put中执行我想要的操作),但它当前是一个简单的q.put(数据),并且我传递的队列被设置为maxsize=0(无限),所以我不知道死锁是从哪里来的。