Tim Peters:

+ Implements a put_nowait method.
+ Adds a corresponding Queue.Full exception.
+ Simplifies the implementation by adding optional "block" args to get() and
put(), and makes the old get_nowait() and new put_nowait() one-line
redirections to get() and put().
+ Uses (much) simpler logic for the nowait cases.
+ Regularizes the doc strings to something closer to "Guido style" <wink>.
+ Converts two stray tabs into spaces.
+ Removes confusing verbiage about the queue "not being available" from the
docstrings -- never knew what that meant as a user, and after digging into
the implementation still didn't know what it was trying to say.
This commit is contained in:
Guido van Rossum 1999-02-08 18:34:01 +00:00
parent 68de0641ce
commit 9e1721fa79
1 changed files with 40 additions and 42 deletions

View File

@ -5,9 +5,14 @@
try:
class Empty(Exception):
pass
class Full(Exception):
pass
except TypeError:
# string based exceptions
Empty = 'Queue.Empty' # Exception raised by get_nowait()
# exception raised by get(block=0)/get_nowait()
Empty = 'Queue.Empty'
# exception raised by put(block=0)/put_nowait()
Full = 'Queue.Full'
class Queue:
def __init__(self, maxsize):
@ -23,32 +28,38 @@ class Queue:
self.fsema = thread.allocate_lock()
def qsize(self):
"""Returns the approximate size of the queue (not reliable!)."""
"""Return the approximate size of the queue (not reliable!)."""
self.mutex.acquire()
n = self._qsize()
self.mutex.release()
return n
def empty(self):
"""Returns 1 if the queue is empty, 0 otherwise (not reliable!)."""
"""Return 1 if the queue is empty, 0 otherwise (not reliable!)."""
self.mutex.acquire()
n = self._empty()
self.mutex.release()
return n
def full(self):
"""Returns 1 if the queue is full, 0 otherwise (not reliable!)."""
"""Return 1 if the queue is full, 0 otherwise (not reliable!)."""
self.mutex.acquire()
n = self._full()
self.mutex.release()
return n
def put(self, item):
def put(self, item, block=1):
"""Put an item into the queue.
If the queue is full, block until a free slot is avaiable.
If optional arg 'block' is 1 (the default), block if
necessary until a free slot is available. Otherwise (block
is 0), put an item on the queue if a free slot is immediately
available, else raise the Full exception.
"""
if block:
self.fsema.acquire()
elif not self.fsema.acquire(0):
raise Full
self.mutex.acquire()
was_empty = self._empty()
self._put(item)
@ -58,12 +69,26 @@ class Queue:
self.fsema.release()
self.mutex.release()
def get(self):
"""Gets and returns an item from the queue.
def put_nowait(self, item):
"""Put an item into the queue without blocking.
This method blocks if necessary until an item is available.
Only enqueue the item if a free slot is immediately available.
Otherwise raise the Full exception.
"""
return self.put(item, 0)
def get(self, block=1):
"""Remove and return an item from the queue.
If optional arg 'block' is 1 (the default), block if
necessary until an item is available. Otherwise (block is 0),
return an item if one is immediately available, else raise the
Empty exception.
"""
if block:
self.esema.acquire()
elif not self.esema.acquire(0):
raise Empty
self.mutex.acquire()
was_full = self._full()
item = self._get()
@ -74,40 +99,13 @@ class Queue:
self.mutex.release()
return item
# Get an item from the queue if one is immediately available,
# raise Empty if the queue is empty or temporarily unavailable
def get_nowait(self):
"""Gets and returns an item from the queue.
"""Remove and return an item from the queue without blocking.
Only gets an item if one is immediately available, Otherwise
this raises the Empty exception if the queue is empty or
temporarily unavailable.
Only get an item if one is immediately available. Otherwise
raise the Empty exception.
"""
locked = self.esema.acquire(0)
self.mutex.acquire()
if self._empty():
# The queue is empty -- we can't have esema
self.mutex.release()
raise Empty
if not locked:
locked = self.esema.acquire(0)
if not locked:
# Somebody else has esema
# but we have mutex --
# go out of their way
self.mutex.release()
raise Empty
was_full = self._full()
item = self._get()
if was_full:
self.fsema.release()
if not self._empty():
self.esema.release()
self.mutex.release()
return item
# XXX Need to define put_nowait() as well.
return self.get(0)
# Override these methods to implement other queue organizations
# (e.g. stack or priority queue).