Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Python's Queue return an approximate size in qsize()?

In the doc of qsize() it says: Return the approximate size of the queue.

Why can't it just return an exact size of this Queue? I understand the Queue may be accessed by multiple threads, but at the moment I call the function I think it's still possible to return the exact size of that moment.

like image 358
FrostNovaZzz Avatar asked Jul 21 '12 11:07

FrostNovaZzz


People also ask

What does the value returned by the Qsize () function of a queue represent?

qsize() – Returns the current queue size. empty() – Returns True if the queue is empty, False otherwise. It is equivalent to qsize()==0. full() – Returns True if the queue is full, False otherwise.

How do I find the size of a python queue?

To get the length of a queue in Python:Use the len() function to get the length of a deque object. Use the qsize() method to get the length of a queue object.

How does Python queue work?

Like stack, queue is a linear data structure that stores items in First In First Out (FIFO) manner. With a queue the least recently added item is removed first. A good example of queue is any queue of consumers for a resource where the consumer that came first is served first.


2 Answers

It is precisely because there are other threads accessing it. By the time you try to use the size you get back from qsize(), the queue could have changed. It would be better if the documentation read something like this:

Returns the size of the queue. Note that in a multi-threaded environment, the size can change at any time, making this only an approximation of the actual size.

like image 81
Ned Batchelder Avatar answered Oct 17 '22 09:10

Ned Batchelder


I agree that 'approximate' isn't the clearest choice of words but as Ned mentions they're trying to point out that simply because the size of the queue at time t1 was 7 doesn't mean it will still be size 7 when you push or pop values later on.

The issue is that assuming that the size you get back from qsize is going to still be correct when you go to push/pop a value off of that queue can behave unexpectedly in a multi-threaded environment.

For example:

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

This is an example of LBYL "Looking before you leap" and it's dangerous because of the potential race condition here when multiple threads are accessing the queue.

In this case you should favor EAFP or "easier to ask for forgiveness than permission" and do the following:

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)
like image 22
stderr Avatar answered Oct 17 '22 08:10

stderr