3

Python 的线程安全QueueQueue.full()对象有一个用以下文档命名的有用函数:

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

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

4

2 回答 2

4

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

如果您的意思是总体上两个线程,那么不,仍然存在竞争条件的机会。

无论哪种方式,真正的问题是您为什么要这样做?试试看,如果失败就捕获异常——这就是 Python 的方式。

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

这具有将来线程安全的优点,并且在任何情况下都避免了竞争条件(不需要线程来导致它,您只需进行调用即可在检查和获取之间偶然更改代码) .

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

于 2012-05-29T14:25:39.023 回答
0

我曾经观察到 Queue() 中 isfull 信息的更新延迟,因为它本身使用了一个特殊的线程(!)来执行诸如 put 和 get 之类的操作。所以即使我(!)只使用一个线程,我也不会依赖这个。也许队列不是。

于 2012-05-29T15:06:05.057 回答