队列为空并在空队列中执行put操作

3
假设我有一个包含两个元素的队列。 我循环遍历队列,使用get弹出项目。我担心一旦弹出第二个元素,循环就会停止,而我需要重新处理它,因为出现了一些错误。所以我把它放回队列,但是由于此时队列已经为空,所以它不会被放回去。
我的循环:
while not queue.empty():
    try:
        item = queue.get()
        do stuff(item):
    except Exception as e:
        queue.put(item)
    queue.task_done()

我阅读了关于 Queue.empty() 的文档,但对于阻塞和它的含义感到困惑。

1个回答

4

如果你正在使用多线程(因为你关心阻塞),通常不建议这样做:

if not queue.empty():  # or 'while' instead of 'if'
    item = queue.get()

因为另一个线程可能会在第一行和第二行之间清空您的 queue,所以现在您的 queue.get() 阻塞,直到有任何新内容进来,这似乎不是您编写的预期行为。基本上,if not queue.empty() 在并发场景下毫无意义。
正确的做法应该是:
try:
    while True:
        item = queue.get(block=False)
        done = False
        while not done:
            try:
                do stuff(item)
                done = True
            except Exception as e:
                pass  # just try again to do stuff
        queue.task_done()
except Empty:
    pass  # no more items

除此之外(如果我们假设没有其他线程可以消耗您的队列),代码将正常工作。然而,我非常怀疑您是否理解(或“理解”,因为问题已经过时)阻塞的概念。如果函数根据文档“阻塞”,那么这意味着在该点处您的代码执行将会停止,直到发生某些事件。time.sleep(1)可能是最好的阻塞函数示例,它会阻塞1秒钟。
PS:我知道这已经过去几年了,但仍然...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接