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.
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.
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.
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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With