blob: 0e6bbf055a469a4e2013c60219e36bd7ac5e5d2b [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
Tim Petersb8c94172001-01-15 22:53:46 +00003class Empty(Exception):
4 "Exception raised by Queue.get(block=0)/get_nowait()."
5 pass
6
7class Full(Exception):
8 "Exception raised by Queue.put(block=0)/put_nowait()."
9 pass
Guido van Rossum9022fce1992-08-25 12:30:44 +000010
11class Queue:
Guido van Rossuma41c6911999-09-09 14:54:28 +000012 def __init__(self, maxsize=0):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000013 """Initialize a queue object with a given maximum size.
Guido van Rossum9022fce1992-08-25 12:30:44 +000014
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000015 If maxsize is <= 0, the queue size is infinite.
16 """
17 import thread
18 self._init(maxsize)
19 self.mutex = thread.allocate_lock()
20 self.esema = thread.allocate_lock()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000021 self.esema.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000022 self.fsema = thread.allocate_lock()
Guido van Rossum9022fce1992-08-25 12:30:44 +000023
Barry Warsaw3d96d521997-11-20 19:56:38 +000024 def qsize(self):
Guido van Rossum9e1721f1999-02-08 18:34:01 +000025 """Return the approximate size of the queue (not reliable!)."""
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000026 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000027 n = self._qsize()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000028 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000029 return n
Barry Warsaw3d96d521997-11-20 19:56:38 +000030
31 def empty(self):
Guido van Rossum9e1721f1999-02-08 18:34:01 +000032 """Return 1 if the queue is empty, 0 otherwise (not reliable!)."""
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000033 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000034 n = self._empty()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000035 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000036 return n
Barry Warsaw3d96d521997-11-20 19:56:38 +000037
38 def full(self):
Guido van Rossum9e1721f1999-02-08 18:34:01 +000039 """Return 1 if the queue is full, 0 otherwise (not reliable!)."""
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000040 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000041 n = self._full()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000042 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000043 return n
Barry Warsaw3d96d521997-11-20 19:56:38 +000044
Guido van Rossum9e1721f1999-02-08 18:34:01 +000045 def put(self, item, block=1):
Guido van Rossumc09e6b11998-04-09 14:25:32 +000046 """Put an item into the queue.
47
Guido van Rossum9e1721f1999-02-08 18:34:01 +000048 If optional arg 'block' is 1 (the default), block if
49 necessary until a free slot is available. Otherwise (block
50 is 0), put an item on the queue if a free slot is immediately
51 available, else raise the Full exception.
52 """
53 if block:
54 self.fsema.acquire()
55 elif not self.fsema.acquire(0):
56 raise Full
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000057 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000058 was_empty = self._empty()
59 self._put(item)
60 if was_empty:
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000061 self.esema.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000062 if not self._full():
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000063 self.fsema.release()
64 self.mutex.release()
Barry Warsaw3d96d521997-11-20 19:56:38 +000065
Guido van Rossum9e1721f1999-02-08 18:34:01 +000066 def put_nowait(self, item):
67 """Put an item into the queue without blocking.
Guido van Rossumc09e6b11998-04-09 14:25:32 +000068
Guido van Rossum9e1721f1999-02-08 18:34:01 +000069 Only enqueue the item if a free slot is immediately available.
70 Otherwise raise the Full exception.
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000071 """
Guido van Rossum9e1721f1999-02-08 18:34:01 +000072 return self.put(item, 0)
Barry Warsaw3d96d521997-11-20 19:56:38 +000073
Guido van Rossum9e1721f1999-02-08 18:34:01 +000074 def get(self, block=1):
75 """Remove and return an item from the queue.
Guido van Rossumc09e6b11998-04-09 14:25:32 +000076
Guido van Rossum9e1721f1999-02-08 18:34:01 +000077 If optional arg 'block' is 1 (the default), block if
78 necessary until an item is available. Otherwise (block is 0),
79 return an item if one is immediately available, else raise the
80 Empty exception.
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000081 """
Guido van Rossum9e1721f1999-02-08 18:34:01 +000082 if block:
83 self.esema.acquire()
84 elif not self.esema.acquire(0):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000085 raise Empty
Guido van Rossum9e1721f1999-02-08 18:34:01 +000086 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000087 was_full = self._full()
88 item = self._get()
89 if was_full:
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000090 self.fsema.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000091 if not self._empty():
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000092 self.esema.release()
93 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000094 return item
Guido van Rossum9022fce1992-08-25 12:30:44 +000095
Guido van Rossum9e1721f1999-02-08 18:34:01 +000096 def get_nowait(self):
97 """Remove and return an item from the queue without blocking.
Guido van Rossum9022fce1992-08-25 12:30:44 +000098
Guido van Rossum9e1721f1999-02-08 18:34:01 +000099 Only get an item if one is immediately available. Otherwise
100 raise the Empty exception.
101 """
102 return self.get(0)
Guido van Rossum9022fce1992-08-25 12:30:44 +0000103
Barry Warsaw3d96d521997-11-20 19:56:38 +0000104 # Override these methods to implement other queue organizations
105 # (e.g. stack or priority queue).
106 # These will only be called with appropriate locks held
Guido van Rossum9022fce1992-08-25 12:30:44 +0000107
Barry Warsaw3d96d521997-11-20 19:56:38 +0000108 # Initialize the queue representation
109 def _init(self, maxsize):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000110 self.maxsize = maxsize
111 self.queue = []
Guido van Rossum9022fce1992-08-25 12:30:44 +0000112
Barry Warsaw3d96d521997-11-20 19:56:38 +0000113 def _qsize(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000114 return len(self.queue)
Guido van Rossum9022fce1992-08-25 12:30:44 +0000115
Jeremy Hyltona05e2932000-06-28 14:48:01 +0000116 # Check whether the queue is empty
Barry Warsaw3d96d521997-11-20 19:56:38 +0000117 def _empty(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000118 return not self.queue
Guido van Rossum9022fce1992-08-25 12:30:44 +0000119
Barry Warsaw3d96d521997-11-20 19:56:38 +0000120 # Check whether the queue is full
121 def _full(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000122 return self.maxsize > 0 and len(self.queue) == self.maxsize
Guido van Rossum9022fce1992-08-25 12:30:44 +0000123
Barry Warsaw3d96d521997-11-20 19:56:38 +0000124 # Put a new item in the queue
125 def _put(self, item):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000126 self.queue.append(item)
Guido van Rossum9022fce1992-08-25 12:30:44 +0000127
Barry Warsaw3d96d521997-11-20 19:56:38 +0000128 # Get an item from the queue
129 def _get(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000130 item = self.queue[0]
131 del self.queue[0]
132 return item