Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Queue.get(block=False) with non-empty Queue. Can it raise Queue.empty?

I'm using python's Queue.Queue to synchronize several threads. First, a Queue is populated with N elements, as in

N = 10
q = Queue.Queue()
for i in range(N):
  q.put(i)

Then, several threads consume the elements from the queue with block=False

q.get(block=False)

My question is: can the previous call to Queue.get() raise Queue.Empty in any of the first N calls?

Thanks!

like image 239
mhernandez Avatar asked May 02 '26 15:05

mhernandez


1 Answers

The first N calls to get() will succeed; q.get(block=False) will only raise Queue.Empty if the queue is actually empty. All the calls to get made by your threads are synchronized, so the first N threads that get the mutex used by the Queue will successfully get an item from the Queue. If you have N+1 or more threads, any get beyond the Nth will raise Queue.Empty. This is fairly easy to see for yourself by looking at the relevant parts of the Queue code, as mentioned by Eric.

class Queue:
    """Create a queue object with a given maximum size.

    If maxsize is <= 0, the queue size is infinite.
    """
    def __init__(self, maxsize=0):
        self.maxsize = maxsize
        self._init(maxsize)
        self.mutex = _threading.Lock()
        self.not_empty = _threading.Condition(self.mutex)
        ... # Stuff we don't care about

    def get(self, block=True, timeout=None):
        self.not_empty.acquire() # Only on thread can hold this at a time
        try:
            if not block:
                if not self._qsize(): # If there's nothing in the Queue
                    raise Empty
            ... # Other stuff we don't care about, since you use block=False
            item = self._get()
            self.not_full.notify()
            return item
        finally:
            self.not_empty.release()

    def _init(self, maxsize):
        self.queue = deque()

    def _qsize(self, len=len):
        return len(self.queue)
like image 54
dano Avatar answered May 05 '26 06:05

dano