blob: 050a9660405ca308f7b4561b9b184c0c4cff2a4c [file] [log] [blame]
Guido van Rossum4acc25b2000-02-02 15:10:15 +00001"""A multi-producer, multi-consumer queue."""
Guido van Rossum9022fce1992-08-25 12:30:44 +00002
Skip Montanaroe99d5ea2001-01-20 19:54:20 +00003__all__ = ["Queue","Empty","Full"]
4
Tim Petersb8c94172001-01-15 22:53:46 +00005class Empty(Exception):
6 "Exception raised by Queue.get(block=0)/get_nowait()."
7 pass
8
9class Full(Exception):
10 "Exception raised by Queue.put(block=0)/put_nowait()."
11 pass
Guido van Rossum9022fce1992-08-25 12:30:44 +000012
13class Queue:
Guido van Rossuma41c6911999-09-09 14:54:28 +000014 def __init__(self, maxsize=0):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000015 """Initialize a queue object with a given maximum size.
Guido van Rossum9022fce1992-08-25 12:30:44 +000016
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000017 If maxsize is <= 0, the queue size is infinite.
18 """
19 import thread
20 self._init(maxsize)
21 self.mutex = thread.allocate_lock()
22 self.esema = thread.allocate_lock()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000023 self.esema.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000024 self.fsema = thread.allocate_lock()
Guido van Rossum9022fce1992-08-25 12:30:44 +000025
Barry Warsaw3d96d521997-11-20 19:56:38 +000026 def qsize(self):
Guido van Rossum9e1721f1999-02-08 18:34:01 +000027 """Return the approximate size of the queue (not reliable!)."""
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000028 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000029 n = self._qsize()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000030 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000031 return n
Barry Warsaw3d96d521997-11-20 19:56:38 +000032
33 def empty(self):
Guido van Rossum9e1721f1999-02-08 18:34:01 +000034 """Return 1 if the queue is empty, 0 otherwise (not reliable!)."""
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000035 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000036 n = self._empty()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000037 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000038 return n
Barry Warsaw3d96d521997-11-20 19:56:38 +000039
40 def full(self):
Guido van Rossum9e1721f1999-02-08 18:34:01 +000041 """Return 1 if the queue is full, 0 otherwise (not reliable!)."""
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000042 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000043 n = self._full()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000044 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000045 return n
Barry Warsaw3d96d521997-11-20 19:56:38 +000046
Guido van Rossum9e1721f1999-02-08 18:34:01 +000047 def put(self, item, block=1):
Guido van Rossumc09e6b11998-04-09 14:25:32 +000048 """Put an item into the queue.
49
Guido van Rossum9e1721f1999-02-08 18:34:01 +000050 If optional arg 'block' is 1 (the default), block if
51 necessary until a free slot is available. Otherwise (block
52 is 0), put an item on the queue if a free slot is immediately
53 available, else raise the Full exception.
54 """
55 if block:
56 self.fsema.acquire()
57 elif not self.fsema.acquire(0):
58 raise Full
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000059 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000060 was_empty = self._empty()
61 self._put(item)
62 if was_empty:
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000063 self.esema.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000064 if not self._full():
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000065 self.fsema.release()
66 self.mutex.release()
Barry Warsaw3d96d521997-11-20 19:56:38 +000067
Guido van Rossum9e1721f1999-02-08 18:34:01 +000068 def put_nowait(self, item):
69 """Put an item into the queue without blocking.
Guido van Rossumc09e6b11998-04-09 14:25:32 +000070
Guido van Rossum9e1721f1999-02-08 18:34:01 +000071 Only enqueue the item if a free slot is immediately available.
72 Otherwise raise the Full exception.
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000073 """
Guido van Rossum9e1721f1999-02-08 18:34:01 +000074 return self.put(item, 0)
Barry Warsaw3d96d521997-11-20 19:56:38 +000075
Guido van Rossum9e1721f1999-02-08 18:34:01 +000076 def get(self, block=1):
77 """Remove and return an item from the queue.
Guido van Rossumc09e6b11998-04-09 14:25:32 +000078
Guido van Rossum9e1721f1999-02-08 18:34:01 +000079 If optional arg 'block' is 1 (the default), block if
80 necessary until an item is available. Otherwise (block is 0),
81 return an item if one is immediately available, else raise the
82 Empty exception.
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000083 """
Guido van Rossum9e1721f1999-02-08 18:34:01 +000084 if block:
85 self.esema.acquire()
86 elif not self.esema.acquire(0):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000087 raise Empty
Guido van Rossum9e1721f1999-02-08 18:34:01 +000088 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000089 was_full = self._full()
90 item = self._get()
91 if was_full:
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000092 self.fsema.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000093 if not self._empty():
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000094 self.esema.release()
95 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000096 return item
Guido van Rossum9022fce1992-08-25 12:30:44 +000097
Guido van Rossum9e1721f1999-02-08 18:34:01 +000098 def get_nowait(self):
99 """Remove and return an item from the queue without blocking.
Guido van Rossum9022fce1992-08-25 12:30:44 +0000100
Guido van Rossum9e1721f1999-02-08 18:34:01 +0000101 Only get an item if one is immediately available. Otherwise
102 raise the Empty exception.
103 """
104 return self.get(0)
Guido van Rossum9022fce1992-08-25 12:30:44 +0000105
Barry Warsaw3d96d521997-11-20 19:56:38 +0000106 # Override these methods to implement other queue organizations
107 # (e.g. stack or priority queue).
108 # These will only be called with appropriate locks held
Guido van Rossum9022fce1992-08-25 12:30:44 +0000109
Barry Warsaw3d96d521997-11-20 19:56:38 +0000110 # Initialize the queue representation
111 def _init(self, maxsize):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000112 self.maxsize = maxsize
113 self.queue = []
Guido van Rossum9022fce1992-08-25 12:30:44 +0000114
Barry Warsaw3d96d521997-11-20 19:56:38 +0000115 def _qsize(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000116 return len(self.queue)
Guido van Rossum9022fce1992-08-25 12:30:44 +0000117
Jeremy Hyltona05e2932000-06-28 14:48:01 +0000118 # Check whether the queue is empty
Barry Warsaw3d96d521997-11-20 19:56:38 +0000119 def _empty(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000120 return not self.queue
Guido van Rossum9022fce1992-08-25 12:30:44 +0000121
Barry Warsaw3d96d521997-11-20 19:56:38 +0000122 # Check whether the queue is full
123 def _full(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000124 return self.maxsize > 0 and len(self.queue) == self.maxsize
Guido van Rossum9022fce1992-08-25 12:30:44 +0000125
Barry Warsaw3d96d521997-11-20 19:56:38 +0000126 # Put a new item in the queue
127 def _put(self, item):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000128 self.queue.append(item)
Guido van Rossum9022fce1992-08-25 12:30:44 +0000129
Barry Warsaw3d96d521997-11-20 19:56:38 +0000130 # Get an item from the queue
131 def _get(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000132 item = self.queue[0]
133 del self.queue[0]
134 return item