mirror of
https://github.com/python/cpython.git
synced 2024-11-26 19:34:19 +08:00
4acc25bd39
1. Comments at the beginning of the module, before functions, and before classes have been turned into docstrings. 2. Tabs are normalized to four spaces. Also, removed the "remove" function from dircmp.py, which reimplements list.remove() (it must have been very old).
139 lines
4.0 KiB
Python
139 lines
4.0 KiB
Python
"""A multi-producer, multi-consumer queue."""
|
|
|
|
# define this exception to be compatible with Python 1.5's class
|
|
# exceptions, but also when -X option is used.
|
|
try:
|
|
class Empty(Exception):
|
|
pass
|
|
class Full(Exception):
|
|
pass
|
|
except TypeError:
|
|
# string based exceptions
|
|
# 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=0):
|
|
"""Initialize a queue object with a given maximum size.
|
|
|
|
If maxsize is <= 0, the queue size is infinite.
|
|
"""
|
|
import thread
|
|
self._init(maxsize)
|
|
self.mutex = thread.allocate_lock()
|
|
self.esema = thread.allocate_lock()
|
|
self.esema.acquire()
|
|
self.fsema = thread.allocate_lock()
|
|
|
|
def qsize(self):
|
|
"""Return the approximate size of the queue (not reliable!)."""
|
|
self.mutex.acquire()
|
|
n = self._qsize()
|
|
self.mutex.release()
|
|
return n
|
|
|
|
def empty(self):
|
|
"""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):
|
|
"""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, block=1):
|
|
"""Put an item into the queue.
|
|
|
|
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)
|
|
if was_empty:
|
|
self.esema.release()
|
|
if not self._full():
|
|
self.fsema.release()
|
|
self.mutex.release()
|
|
|
|
def put_nowait(self, item):
|
|
"""Put an item into the queue without blocking.
|
|
|
|
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()
|
|
if was_full:
|
|
self.fsema.release()
|
|
if not self._empty():
|
|
self.esema.release()
|
|
self.mutex.release()
|
|
return item
|
|
|
|
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
|
|
# (e.g. stack or priority queue).
|
|
# These will only be called with appropriate locks held
|
|
|
|
# Initialize the queue representation
|
|
def _init(self, maxsize):
|
|
self.maxsize = maxsize
|
|
self.queue = []
|
|
|
|
def _qsize(self):
|
|
return len(self.queue)
|
|
|
|
# Check wheter the queue is empty
|
|
def _empty(self):
|
|
return not self.queue
|
|
|
|
# Check whether the queue is full
|
|
def _full(self):
|
|
return self.maxsize > 0 and len(self.queue) == self.maxsize
|
|
|
|
# Put a new item in the queue
|
|
def _put(self, item):
|
|
self.queue.append(item)
|
|
|
|
# Get an item from the queue
|
|
def _get(self):
|
|
item = self.queue[0]
|
|
del self.queue[0]
|
|
return item
|