blob: cb04006f11d2dc32cc2ab24744e922a681c7cace [file] [log] [blame]
Guido van Rossumaad67612000-05-08 17:31:04 +00001"""A multi-producer, multi-consumer queue."""
Guido van Rossum5c971671996-07-22 15:23:25 +00002
Guido van Rossum0b233481997-11-26 15:44:34 +00003# define this exception to be compatible with Python 1.5's class
4# exceptions, but also when -X option is used.
5try:
6 class Empty(Exception):
Guido van Rossum548703a1998-03-26 22:14:20 +00007 pass
Guido van Rossum2e7840f1999-02-09 18:40:13 +00008 class Full(Exception):
9 pass
Guido van Rossum0b233481997-11-26 15:44:34 +000010except TypeError:
11 # string based exceptions
Guido van Rossum2e7840f1999-02-09 18:40:13 +000012 # exception raised by get(block=0)/get_nowait()
13 Empty = 'Queue.Empty'
14 # exception raised by put(block=0)/put_nowait()
15 Full = 'Queue.Full'
Guido van Rossum5c971671996-07-22 15:23:25 +000016
17class Queue:
Guido van Rossumaad67612000-05-08 17:31:04 +000018 def __init__(self, maxsize=0):
Guido van Rossum548703a1998-03-26 22:14:20 +000019 """Initialize a queue object with a given maximum size.
Guido van Rossum5c971671996-07-22 15:23:25 +000020
Guido van Rossum548703a1998-03-26 22:14:20 +000021 If maxsize is <= 0, the queue size is infinite.
22 """
23 import thread
24 self._init(maxsize)
25 self.mutex = thread.allocate_lock()
26 self.esema = thread.allocate_lock()
Guido van Rossume03c0501998-08-12 02:38:11 +000027 self.esema.acquire()
Guido van Rossum548703a1998-03-26 22:14:20 +000028 self.fsema = thread.allocate_lock()
Guido van Rossum5c971671996-07-22 15:23:25 +000029
Guido van Rossum0b233481997-11-26 15:44:34 +000030 def qsize(self):
Guido van Rossum2e7840f1999-02-09 18:40:13 +000031 """Return the approximate size of the queue (not reliable!)."""
Guido van Rossume03c0501998-08-12 02:38:11 +000032 self.mutex.acquire()
Guido van Rossum548703a1998-03-26 22:14:20 +000033 n = self._qsize()
Guido van Rossume03c0501998-08-12 02:38:11 +000034 self.mutex.release()
Guido van Rossum548703a1998-03-26 22:14:20 +000035 return n
Guido van Rossum0b233481997-11-26 15:44:34 +000036
37 def empty(self):
Guido van Rossum2e7840f1999-02-09 18:40:13 +000038 """Return 1 if the queue is empty, 0 otherwise (not reliable!)."""
Guido van Rossume03c0501998-08-12 02:38:11 +000039 self.mutex.acquire()
Guido van Rossum548703a1998-03-26 22:14:20 +000040 n = self._empty()
Guido van Rossume03c0501998-08-12 02:38:11 +000041 self.mutex.release()
Guido van Rossum548703a1998-03-26 22:14:20 +000042 return n
Guido van Rossum0b233481997-11-26 15:44:34 +000043
44 def full(self):
Guido van Rossum2e7840f1999-02-09 18:40:13 +000045 """Return 1 if the queue is full, 0 otherwise (not reliable!)."""
Guido van Rossume03c0501998-08-12 02:38:11 +000046 self.mutex.acquire()
Guido van Rossum548703a1998-03-26 22:14:20 +000047 n = self._full()
Guido van Rossume03c0501998-08-12 02:38:11 +000048 self.mutex.release()
Guido van Rossum548703a1998-03-26 22:14:20 +000049 return n
Guido van Rossum0b233481997-11-26 15:44:34 +000050
Guido van Rossum2e7840f1999-02-09 18:40:13 +000051 def put(self, item, block=1):
Guido van Rossumbb080661998-04-09 21:47:39 +000052 """Put an item into the queue.
53
Guido van Rossum2e7840f1999-02-09 18:40:13 +000054 If optional arg 'block' is 1 (the default), block if
55 necessary until a free slot is available. Otherwise (block
56 is 0), put an item on the queue if a free slot is immediately
57 available, else raise the Full exception.
58 """
59 if block:
60 self.fsema.acquire()
61 elif not self.fsema.acquire(0):
62 raise Full
Guido van Rossume03c0501998-08-12 02:38:11 +000063 self.mutex.acquire()
Guido van Rossum548703a1998-03-26 22:14:20 +000064 was_empty = self._empty()
65 self._put(item)
66 if was_empty:
Guido van Rossume03c0501998-08-12 02:38:11 +000067 self.esema.release()
Guido van Rossum548703a1998-03-26 22:14:20 +000068 if not self._full():
Guido van Rossume03c0501998-08-12 02:38:11 +000069 self.fsema.release()
70 self.mutex.release()
Guido van Rossum0b233481997-11-26 15:44:34 +000071
Guido van Rossum2e7840f1999-02-09 18:40:13 +000072 def put_nowait(self, item):
73 """Put an item into the queue without blocking.
Guido van Rossumbb080661998-04-09 21:47:39 +000074
Guido van Rossum2e7840f1999-02-09 18:40:13 +000075 Only enqueue the item if a free slot is immediately available.
76 Otherwise raise the Full exception.
Guido van Rossum548703a1998-03-26 22:14:20 +000077 """
Guido van Rossum2e7840f1999-02-09 18:40:13 +000078 return self.put(item, 0)
Guido van Rossum0b233481997-11-26 15:44:34 +000079
Guido van Rossum2e7840f1999-02-09 18:40:13 +000080 def get(self, block=1):
81 """Remove and return an item from the queue.
Guido van Rossumbb080661998-04-09 21:47:39 +000082
Guido van Rossum2e7840f1999-02-09 18:40:13 +000083 If optional arg 'block' is 1 (the default), block if
84 necessary until an item is available. Otherwise (block is 0),
85 return an item if one is immediately available, else raise the
86 Empty exception.
Guido van Rossum548703a1998-03-26 22:14:20 +000087 """
Guido van Rossum2e7840f1999-02-09 18:40:13 +000088 if block:
89 self.esema.acquire()
90 elif not self.esema.acquire(0):
Guido van Rossum548703a1998-03-26 22:14:20 +000091 raise Empty
Guido van Rossum2e7840f1999-02-09 18:40:13 +000092 self.mutex.acquire()
Guido van Rossum548703a1998-03-26 22:14:20 +000093 was_full = self._full()
94 item = self._get()
95 if was_full:
Guido van Rossume03c0501998-08-12 02:38:11 +000096 self.fsema.release()
Guido van Rossum548703a1998-03-26 22:14:20 +000097 if not self._empty():
Guido van Rossume03c0501998-08-12 02:38:11 +000098 self.esema.release()
99 self.mutex.release()
Guido van Rossum548703a1998-03-26 22:14:20 +0000100 return item
Guido van Rossum5c971671996-07-22 15:23:25 +0000101
Guido van Rossum2e7840f1999-02-09 18:40:13 +0000102 def get_nowait(self):
103 """Remove and return an item from the queue without blocking.
Guido van Rossum5c971671996-07-22 15:23:25 +0000104
Guido van Rossum2e7840f1999-02-09 18:40:13 +0000105 Only get an item if one is immediately available. Otherwise
106 raise the Empty exception.
107 """
108 return self.get(0)
Guido van Rossum5c971671996-07-22 15:23:25 +0000109
Guido van Rossum0b233481997-11-26 15:44:34 +0000110 # Override these methods to implement other queue organizations
111 # (e.g. stack or priority queue).
112 # These will only be called with appropriate locks held
Guido van Rossum5c971671996-07-22 15:23:25 +0000113
Guido van Rossum0b233481997-11-26 15:44:34 +0000114 # Initialize the queue representation
115 def _init(self, maxsize):
Guido van Rossum548703a1998-03-26 22:14:20 +0000116 self.maxsize = maxsize
117 self.queue = []
Guido van Rossum5c971671996-07-22 15:23:25 +0000118
Guido van Rossum0b233481997-11-26 15:44:34 +0000119 def _qsize(self):
Guido van Rossum548703a1998-03-26 22:14:20 +0000120 return len(self.queue)
Guido van Rossum5c971671996-07-22 15:23:25 +0000121
Guido van Rossum0b233481997-11-26 15:44:34 +0000122 # Check wheter the queue is empty
123 def _empty(self):
Guido van Rossum548703a1998-03-26 22:14:20 +0000124 return not self.queue
Guido van Rossum5c971671996-07-22 15:23:25 +0000125
Guido van Rossum0b233481997-11-26 15:44:34 +0000126 # Check whether the queue is full
127 def _full(self):
Guido van Rossum548703a1998-03-26 22:14:20 +0000128 return self.maxsize > 0 and len(self.queue) == self.maxsize
Guido van Rossum5c971671996-07-22 15:23:25 +0000129
Guido van Rossum0b233481997-11-26 15:44:34 +0000130 # Put a new item in the queue
131 def _put(self, item):
Guido van Rossum548703a1998-03-26 22:14:20 +0000132 self.queue.append(item)
Guido van Rossum5c971671996-07-22 15:23:25 +0000133
Guido van Rossum0b233481997-11-26 15:44:34 +0000134 # Get an item from the queue
135 def _get(self):
Guido van Rossum548703a1998-03-26 22:14:20 +0000136 item = self.queue[0]
137 del self.queue[0]
138 return item