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:
parent
68de0641ce
commit
9e1721fa79
82
Lib/Queue.py
82
Lib/Queue.py
|
@ -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).
|
||||||
|
|
Loading…
Reference in New Issue