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: try:
class Empty(Exception): class Empty(Exception):
pass pass
class Full(Exception):
pass
except TypeError: except TypeError:
# string based exceptions # 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: class Queue:
def __init__(self, maxsize): def __init__(self, maxsize):
@ -23,32 +28,38 @@ class Queue:
self.fsema = thread.allocate_lock() self.fsema = thread.allocate_lock()
def qsize(self): def qsize(self):
"""Returns the approximate size of the queue (not reliable!).""" """Return the approximate size of the queue (not reliable!)."""
self.mutex.acquire() self.mutex.acquire()
n = self._qsize() n = self._qsize()
self.mutex.release() self.mutex.release()
return n return n
def empty(self): 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() self.mutex.acquire()
n = self._empty() n = self._empty()
self.mutex.release() self.mutex.release()
return n return n
def full(self): 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() self.mutex.acquire()
n = self._full() n = self._full()
self.mutex.release() self.mutex.release()
return n return n
def put(self, item): def put(self, item, block=1):
"""Put an item into the queue. """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
self.fsema.acquire() 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() self.mutex.acquire()
was_empty = self._empty() was_empty = self._empty()
self._put(item) self._put(item)
@ -58,45 +69,27 @@ class Queue:
self.fsema.release() self.fsema.release()
self.mutex.release() self.mutex.release()
def get(self): def put_nowait(self, item):
"""Gets and returns an item from the queue. """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.
""" """
self.esema.acquire() return self.put(item, 0)
self.mutex.acquire()
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
# Get an item from the queue if one is immediately available, def get(self, block=1):
# raise Empty if the queue is empty or temporarily unavailable """Remove and return an item from the queue.
def get_nowait(self):
"""Gets and returns an item from the queue.
Only gets an item if one is immediately available, Otherwise If optional arg 'block' is 1 (the default), block if
this raises the Empty exception if the queue is empty or necessary until an item is available. Otherwise (block is 0),
temporarily unavailable. return an item if one is immediately available, else raise the
Empty exception.
""" """
locked = self.esema.acquire(0) if block:
self.mutex.acquire() self.esema.acquire()
if self._empty(): elif not self.esema.acquire(0):
# The queue is empty -- we can't have esema
self.mutex.release()
raise Empty raise Empty
if not locked: self.mutex.acquire()
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() was_full = self._full()
item = self._get() item = self._get()
if was_full: if was_full:
@ -106,8 +99,13 @@ class Queue:
self.mutex.release() self.mutex.release()
return item return item
# XXX Need to define put_nowait() as well. def get_nowait(self):
"""Remove and return an item from the queue without blocking.
Only get an item if one is immediately available. Otherwise
raise the Empty exception.
"""
return self.get(0)
# Override these methods to implement other queue organizations # Override these methods to implement other queue organizations
# (e.g. stack or priority queue). # (e.g. stack or priority queue).