队列空方法坏了吗?

is Queue empty method broken?

如何检查队列是否为空? 运行 下面的代码:

from multiprocessing import Queue

q = Queue()
print(q.empty())

q.put("a")
print(q.empty())

呈现:

True
True

添加元素后不应该q.empty()returnFalse吗?

put方法是异步的,因此在检查元素时队列可能仍然是空的。在 putempty() returns False.

之后添加 time.sleep(1)

两种可能的解决方案:

  1. 使用 queue.Queue 而不是 multiprocessing.Queue: 他们之间有些 differences in doc:

They differ in that Queue lacks the task_done() and join() methods introduced into Python 2.5's queue.Queue class.

from queue import Queue
q = Queue()
print(q.empty())
q.put("a")
print(q.empty())
  1. 或者就像@Hans Musgrave 在评论中所说的那样。time.sleep(1) 不是 guaranteed.You 可以使用 time.sleep(0) 代替:
from multiprocessing import Queue
import time
q = Queue()
print(q.empty())
time.sleep(0)
q.put("a")
print(q.empty())

他们都给我:

True
False

关于为什么 sleep(0)零值会导致线程将其剩余时间片放弃给任何其他准备好 运行 的线程。如果没有其他线程准备运行,函数returns立即执行,线程继续执行 cpu放弃资源,执行q.emety() task.That我想的

稳定的方法是使用queue.Queuequeues.SimpleQueue

官方推荐的方案是使用Manager.Queue.

引用自Python docs

Note:
When an object is put on a queue, the object is pickled and a background thread later flushes the pickled data to an underlying pipe. This has some consequences which are a little surprising, but should not cause any practical difficulties – if they really bother you then you can instead use a queue created with a manager.
1. After putting an object on an empty queue there may be an infinitesimal delay before the queue’s empty() method returns False and get_nowait() can return without raising Queue.Empty.
2. If multiple processes are enqueuing objects, it is possible for the objects to be received at the other end out-of-order. However, objects enqueued by the same process will always be in the expected order with respect to each other.