【发布时间】:2012-07-21 11:54:37
【问题描述】:
在 qsize() 的 doc 中它说:返回队列的近似大小。
为什么它不能只返回这个队列的确切大小?我知道队列可能被多个线程访问,但在我调用该函数的那一刻,我认为它仍然可以返回那个时刻的确切大小。
【问题讨论】:
-
什么时候?队列大小可能在方法返回期间发生了变化。
标签: python multithreading
在 qsize() 的 doc 中它说:返回队列的近似大小。
为什么它不能只返回这个队列的确切大小?我知道队列可能被多个线程访问,但在我调用该函数的那一刻,我认为它仍然可以返回那个时刻的确切大小。
【问题讨论】:
标签: python multithreading
正是因为有其他线程在访问它。当您尝试使用从 qsize() 返回的大小时,队列可能已经改变。如果文档是这样写的会更好:
返回队列的大小。请注意,在多线程环境中,大小可以随时更改,这只是实际大小的近似值。
【讨论】:
我同意“近似”不是最清晰的词选择,但正如 Ned 提到的,他们试图指出,仅仅因为 t1 时队列的大小为 7 并不意味着它仍然会当您稍后推送或弹出值时,大小为 7。
问题在于,假设您从 qsize 返回的大小仍然正确,当您从该队列中推送/弹出一个值时,可能会在多线程环境中出现意外行为。
例如:
q = Queue()
if q.qsize > 0: # size is 1 here
# another thread runs here and gets an item from your queue
# this get fails and throws an exception in your thread:
item = q.get(False)
# do whatever processing with item you need to do
这是一个 LBYL 的示例“在你跳跃之前先看一下”,它很危险,因为当多个线程访问队列时,这里可能会出现竞争条件。
在这种情况下,您应该支持 EAFP 或“请求宽恕比请求许可更容易”并执行以下操作:
from Queue import Queue, Empty
import time
q = Queue()
try:
item = q.get(False)
# do whatever processing with item you need to do
except Empty:
time.sleep(1)
【讨论】:
q.get 是获取项目的最佳线程安全方式。