Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is Queue empty method broken?

How can I check if a Queue is empty? Running below code :

from multiprocessing import Queue

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

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

renders:

True
True

Shouldnt q.empty() return False after an element has been added?

like image 444
blue-sky Avatar asked Oct 24 '25 05:10

blue-sky


2 Answers

Two possible solutions:

  1. Use queue.Queue instead of multiprocessing.Queue: Some differences in doc between them:

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. Or just like @Hans Musgrave said in comment.time.sleep(1) is not guaranteed.You could use time.sleep(0) instead:
from multiprocessing import Queue
import time
q = Queue()
print(q.empty())
time.sleep(0)
q.put("a")
print(q.empty())

All of them give me:

True
False

About why sleep(0), A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If there are no other threads ready to run, the function returns immediately, and the thread continues execution cpu gives up resources, to execute q.emety() task.That's what I think.

The stable method is to use queue.Queue or queues.SimpleQueue.

like image 200
jizhihaoSAMA Avatar answered Oct 26 '25 19:10

jizhihaoSAMA


The officially recommended solution is to use Manager.Queue.

Quoting from 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.

like image 43
Anmol Singh Jaggi Avatar answered Oct 26 '25 20:10

Anmol Singh Jaggi