使用单个线程时Queue.full()是否可靠?

时间:2012-05-29 14:18:54

标签: python multithreading thread-safety queue

Python的thread-safe Queue对象有一个名为Queue.full()的有用函数,其中包含以下文档:

  

如果队列已满,则返回True,否则返回False。如果full()返回   是的,它不保证后续调用get()不会   块。同样,如果full()返回False,则不保证a   后续调用put()不会阻塞。

很明显,在多线程场景中,队列中有多个线程put()项和多个线程get()项,存在竞争条件。但是,如果只有一个线程使用put(),而使用get()的一个不同线程不能信任full()的值?
这是一个特定于Python实现的问题吗?如果是这样,CPython的答案是什么?

2 个答案:

答案 0 :(得分:4)

如果你的意思是你只使用一个线程来做所有事情,那么是的。如果没有别的东西可以访问它,它就无法改变。

如果你的意思是整体上有两个线程,那么不存在竞争条件。

无论哪种方式,真正的问题是你为什么要这样做?尝试一下,如果失败则捕获异常 - 这就是Python方式。

try:
    some_queue.get_nowait()
except queue.Empty:
    do_something_else()

这具有以后保持线程安全的优点,并且在任何情况下都避免了竞争条件(不需要线程来引起它,你可以只调用一个更改检查和获取之间的代码的调用偶然)。

编辑:正如larsmans在下面的评论中指出的,在与竞争条件有关的其他问题中,CPython标记为可能会在某些时候删除 >,所以还有另一个原因可以避免它。

答案 1 :(得分:0)

我曾经观察过Queue()中isfull-information的延迟更新,因为它本身使用一个特殊的线程(!)来执行put和get之类的操作。即使我(!)只使用一个线程,我也不会依赖于此。也许Queue不是。