blob: 22908550e09cc1ee1ac7e667798a38c9e9d488cb [file] [log] [blame]
Jeremy Hylton92bb6e72002-08-14 19:25:42 +00001"""Thread module emulating a subset of Java's threading model."""
Guido van Rossum7f5013a1998-04-09 22:01:42 +00002
Fred Drakea8725952002-12-30 23:32:50 +00003import sys as _sys
4
5try:
6 import thread
7except ImportError:
8 del _sys.modules[__name__]
9 raise
10
Jeffrey Yasskin105f3d42008-03-31 00:35:53 +000011import warnings
Benjamin Petersonf4395602008-06-11 17:50:00 +000012
Fred Drakea8725952002-12-30 23:32:50 +000013from time import time as _time, sleep as _sleep
Neil Schemenauerf607fc52003-11-05 23:03:00 +000014from traceback import format_exc as _format_exc
Guido van Rossum7f5013a1998-04-09 22:01:42 +000015
Benjamin Peterson973e6c22008-09-01 23:12:58 +000016# Note regarding PEP 8 compliant aliases
17# This threading model was originally inspired by Java, and inherited
18# the convention of camelCase function and method names from that
19# language. While those names are not in any imminent danger of being
20# deprecated, starting with Python 2.6, the module now provides a
21# PEP 8 compliant alias for any such method name.
22# Using the new PEP 8 compliant names also facilitates substitution
23# with the multiprocessing module, which doesn't provide the old
24# Java inspired names.
25
26
Guido van Rossum7f5013a1998-04-09 22:01:42 +000027# Rename some stuff so "from threading import *" is safe
Benjamin Peterson13f73822008-06-11 18:02:31 +000028__all__ = ['activeCount', 'active_count', 'Condition', 'currentThread',
29 'current_thread', 'enumerate', 'Event',
Tim Peters685e6972003-06-29 16:50:06 +000030 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
Andrew MacIntyre92913322006-06-13 15:04:24 +000031 'Timer', 'setprofile', 'settrace', 'local', 'stack_size']
Guido van Rossum7f5013a1998-04-09 22:01:42 +000032
Guido van Rossum7f5013a1998-04-09 22:01:42 +000033_start_new_thread = thread.start_new_thread
34_allocate_lock = thread.allocate_lock
35_get_ident = thread.get_ident
Jeremy Hyltonb5fc7492000-06-01 01:17:17 +000036ThreadError = thread.error
Guido van Rossum7f5013a1998-04-09 22:01:42 +000037del thread
38
Guido van Rossum7f5013a1998-04-09 22:01:42 +000039
Jeffrey Yasskin105f3d42008-03-31 00:35:53 +000040# sys.exc_clear is used to work around the fact that except blocks
41# don't fully clear the exception until 3.0.
42warnings.filterwarnings('ignore', category=DeprecationWarning,
43 module='threading', message='sys.exc_clear')
44
Tim Peters59aba122003-07-01 20:01:55 +000045# Debug support (adapted from ihooks.py).
46# All the major classes here derive from _Verbose. We force that to
47# be a new-style class so that all the major classes here are new-style.
48# This helps debugging (type(instance) is more revealing for instances
49# of new-style classes).
Guido van Rossum7f5013a1998-04-09 22:01:42 +000050
Tim Peters0939fac2003-07-01 19:28:44 +000051_VERBOSE = False
Guido van Rossum7f5013a1998-04-09 22:01:42 +000052
53if __debug__:
54
Tim Peters59aba122003-07-01 20:01:55 +000055 class _Verbose(object):
Guido van Rossum7f5013a1998-04-09 22:01:42 +000056
57 def __init__(self, verbose=None):
58 if verbose is None:
59 verbose = _VERBOSE
60 self.__verbose = verbose
61
62 def _note(self, format, *args):
63 if self.__verbose:
64 format = format % args
Antoine Pitrou47900cf2010-12-17 17:45:12 +000065 # Issue #4188: calling current_thread() can incur an infinite
66 # recursion if it has to create a DummyThread on the fly.
67 ident = _get_ident()
68 try:
69 name = _active[ident].name
70 except KeyError:
71 name = "<OS thread %d>" % ident
72 format = "%s: %s\n" % (name, format)
Guido van Rossum7f5013a1998-04-09 22:01:42 +000073 _sys.stderr.write(format)
74
75else:
76 # Disable this when using "python -O"
Tim Peters59aba122003-07-01 20:01:55 +000077 class _Verbose(object):
Guido van Rossum7f5013a1998-04-09 22:01:42 +000078 def __init__(self, verbose=None):
79 pass
80 def _note(self, *args):
81 pass
82
Jeremy Hyltonbfccb352003-06-29 16:58:41 +000083# Support for profile and trace hooks
84
85_profile_hook = None
86_trace_hook = None
87
88def setprofile(func):
89 global _profile_hook
90 _profile_hook = func
Tim Petersd1b108b2003-06-29 17:24:17 +000091
Jeremy Hyltonbfccb352003-06-29 16:58:41 +000092def settrace(func):
93 global _trace_hook
94 _trace_hook = func
Guido van Rossum7f5013a1998-04-09 22:01:42 +000095
96# Synchronization classes
97
98Lock = _allocate_lock
99
100def RLock(*args, **kwargs):
Guido van Rossum68468eb2003-02-27 20:14:51 +0000101 return _RLock(*args, **kwargs)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000102
103class _RLock(_Verbose):
Tim Petersb90f89a2001-01-15 03:26:36 +0000104
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000105 def __init__(self, verbose=None):
106 _Verbose.__init__(self, verbose)
107 self.__block = _allocate_lock()
108 self.__owner = None
109 self.__count = 0
110
111 def __repr__(self):
Nick Coghlanf8bbaa92007-07-31 13:38:01 +0000112 owner = self.__owner
Antoine Pitroud7158d42009-11-09 16:00:11 +0000113 try:
114 owner = _active[owner].name
115 except KeyError:
116 pass
117 return "<%s owner=%r count=%d>" % (
118 self.__class__.__name__, owner, self.__count)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000119
120 def acquire(self, blocking=1):
Antoine Pitroud7158d42009-11-09 16:00:11 +0000121 me = _get_ident()
122 if self.__owner == me:
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000123 self.__count = self.__count + 1
124 if __debug__:
125 self._note("%s.acquire(%s): recursive success", self, blocking)
126 return 1
127 rc = self.__block.acquire(blocking)
128 if rc:
129 self.__owner = me
130 self.__count = 1
131 if __debug__:
Brett Cannon90cece72005-01-27 22:48:30 +0000132 self._note("%s.acquire(%s): initial success", self, blocking)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000133 else:
134 if __debug__:
135 self._note("%s.acquire(%s): failure", self, blocking)
136 return rc
137
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000138 __enter__ = acquire
139
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000140 def release(self):
Antoine Pitroud7158d42009-11-09 16:00:11 +0000141 if self.__owner != _get_ident():
Georg Brandle1254d72009-10-14 15:51:48 +0000142 raise RuntimeError("cannot release un-acquired lock")
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000143 self.__count = count = self.__count - 1
144 if not count:
145 self.__owner = None
146 self.__block.release()
147 if __debug__:
148 self._note("%s.release(): final release", self)
149 else:
150 if __debug__:
151 self._note("%s.release(): non-final release", self)
152
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000153 def __exit__(self, t, v, tb):
154 self.release()
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000155
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000156 # Internal methods used by condition variables
157
Brett Cannon20050502008-08-02 03:13:46 +0000158 def _acquire_restore(self, count_owner):
159 count, owner = count_owner
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000160 self.__block.acquire()
161 self.__count = count
162 self.__owner = owner
163 if __debug__:
164 self._note("%s._acquire_restore()", self)
165
166 def _release_save(self):
167 if __debug__:
168 self._note("%s._release_save()", self)
169 count = self.__count
170 self.__count = 0
171 owner = self.__owner
172 self.__owner = None
173 self.__block.release()
174 return (count, owner)
175
176 def _is_owned(self):
Antoine Pitroud7158d42009-11-09 16:00:11 +0000177 return self.__owner == _get_ident()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000178
179
180def Condition(*args, **kwargs):
Guido van Rossum68468eb2003-02-27 20:14:51 +0000181 return _Condition(*args, **kwargs)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000182
183class _Condition(_Verbose):
184
185 def __init__(self, lock=None, verbose=None):
186 _Verbose.__init__(self, verbose)
187 if lock is None:
188 lock = RLock()
189 self.__lock = lock
190 # Export the lock's acquire() and release() methods
191 self.acquire = lock.acquire
192 self.release = lock.release
193 # If the lock defines _release_save() and/or _acquire_restore(),
194 # these override the default implementations (which just call
195 # release() and acquire() on the lock). Ditto for _is_owned().
196 try:
197 self._release_save = lock._release_save
198 except AttributeError:
199 pass
200 try:
201 self._acquire_restore = lock._acquire_restore
202 except AttributeError:
203 pass
204 try:
205 self._is_owned = lock._is_owned
206 except AttributeError:
207 pass
208 self.__waiters = []
209
Guido van Rossumda5b7012006-05-02 19:47:52 +0000210 def __enter__(self):
211 return self.__lock.__enter__()
212
213 def __exit__(self, *args):
214 return self.__lock.__exit__(*args)
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000215
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000216 def __repr__(self):
217 return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
218
219 def _release_save(self):
220 self.__lock.release() # No state to save
221
222 def _acquire_restore(self, x):
223 self.__lock.acquire() # Ignore saved state
224
225 def _is_owned(self):
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000226 # Return True if lock is owned by current_thread.
Jeremy Hyltonaf7fde72002-08-14 17:43:59 +0000227 # This method is called only if __lock doesn't have _is_owned().
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000228 if self.__lock.acquire(0):
229 self.__lock.release()
Tim Petersbc0e9102002-04-04 22:55:58 +0000230 return False
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000231 else:
Tim Petersbc0e9102002-04-04 22:55:58 +0000232 return True
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000233
234 def wait(self, timeout=None):
Collin Winter50b79ce2007-06-06 00:17:35 +0000235 if not self._is_owned():
Georg Brandle1254d72009-10-14 15:51:48 +0000236 raise RuntimeError("cannot wait on un-acquired lock")
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000237 waiter = _allocate_lock()
238 waiter.acquire()
239 self.__waiters.append(waiter)
240 saved_state = self._release_save()
Tim Petersc951bf92001-04-02 20:15:57 +0000241 try: # restore state no matter what (e.g., KeyboardInterrupt)
242 if timeout is None:
243 waiter.acquire()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000244 if __debug__:
Tim Petersc951bf92001-04-02 20:15:57 +0000245 self._note("%s.wait(): got it", self)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000246 else:
Tim Petersa6a4f272001-08-12 00:41:33 +0000247 # Balancing act: We can't afford a pure busy loop, so we
248 # have to sleep; but if we sleep the whole timeout time,
249 # we'll be unresponsive. The scheme here sleeps very
250 # little at first, longer as time goes on, but never longer
251 # than 20 times per second (or the timeout time remaining).
Tim Petersc951bf92001-04-02 20:15:57 +0000252 endtime = _time() + timeout
Tim Petersa6a4f272001-08-12 00:41:33 +0000253 delay = 0.0005 # 500 us -> initial delay of 1 ms
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000254 while True:
Tim Petersc951bf92001-04-02 20:15:57 +0000255 gotit = waiter.acquire(0)
Tim Petersa6a4f272001-08-12 00:41:33 +0000256 if gotit:
Tim Petersc951bf92001-04-02 20:15:57 +0000257 break
Tim Petersa6a4f272001-08-12 00:41:33 +0000258 remaining = endtime - _time()
259 if remaining <= 0:
260 break
261 delay = min(delay * 2, remaining, .05)
Tim Petersc951bf92001-04-02 20:15:57 +0000262 _sleep(delay)
Tim Petersc951bf92001-04-02 20:15:57 +0000263 if not gotit:
264 if __debug__:
265 self._note("%s.wait(%s): timed out", self, timeout)
266 try:
267 self.__waiters.remove(waiter)
268 except ValueError:
269 pass
270 else:
271 if __debug__:
272 self._note("%s.wait(%s): got it", self, timeout)
273 finally:
274 self._acquire_restore(saved_state)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000275
276 def notify(self, n=1):
Collin Winter50b79ce2007-06-06 00:17:35 +0000277 if not self._is_owned():
Georg Brandle1254d72009-10-14 15:51:48 +0000278 raise RuntimeError("cannot notify on un-acquired lock")
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000279 __waiters = self.__waiters
280 waiters = __waiters[:n]
281 if not waiters:
282 if __debug__:
283 self._note("%s.notify(): no waiters", self)
284 return
285 self._note("%s.notify(): notifying %d waiter%s", self, n,
286 n!=1 and "s" or "")
287 for waiter in waiters:
288 waiter.release()
289 try:
290 __waiters.remove(waiter)
291 except ValueError:
292 pass
293
Benjamin Peterson973e6c22008-09-01 23:12:58 +0000294 def notifyAll(self):
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000295 self.notify(len(self.__waiters))
296
Benjamin Peterson973e6c22008-09-01 23:12:58 +0000297 notify_all = notifyAll
Benjamin Petersonf4395602008-06-11 17:50:00 +0000298
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000299
300def Semaphore(*args, **kwargs):
Guido van Rossum68468eb2003-02-27 20:14:51 +0000301 return _Semaphore(*args, **kwargs)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000302
303class _Semaphore(_Verbose):
304
Andrew M. Kuchling39d3bfc2000-02-29 00:10:24 +0000305 # After Tim Peters' semaphore class, but not quite the same (no maximum)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000306
307 def __init__(self, value=1, verbose=None):
Collin Winter50b79ce2007-06-06 00:17:35 +0000308 if value < 0:
309 raise ValueError("semaphore initial value must be >= 0")
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000310 _Verbose.__init__(self, verbose)
311 self.__cond = Condition(Lock())
312 self.__value = value
313
314 def acquire(self, blocking=1):
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000315 rc = False
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000316 self.__cond.acquire()
317 while self.__value == 0:
318 if not blocking:
319 break
Skip Montanarob446fc72001-08-19 04:25:24 +0000320 if __debug__:
321 self._note("%s.acquire(%s): blocked waiting, value=%s",
322 self, blocking, self.__value)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000323 self.__cond.wait()
324 else:
325 self.__value = self.__value - 1
Skip Montanarob446fc72001-08-19 04:25:24 +0000326 if __debug__:
Skip Montanaroae8454a2001-08-19 05:53:47 +0000327 self._note("%s.acquire: success, value=%s",
328 self, self.__value)
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000329 rc = True
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000330 self.__cond.release()
331 return rc
332
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000333 __enter__ = acquire
334
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000335 def release(self):
336 self.__cond.acquire()
337 self.__value = self.__value + 1
Skip Montanarob446fc72001-08-19 04:25:24 +0000338 if __debug__:
Skip Montanaroae8454a2001-08-19 05:53:47 +0000339 self._note("%s.release: success, value=%s",
340 self, self.__value)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000341 self.__cond.notify()
342 self.__cond.release()
343
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000344 def __exit__(self, t, v, tb):
345 self.release()
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000346
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000347
Skip Montanaroe428bb72001-08-20 20:27:58 +0000348def BoundedSemaphore(*args, **kwargs):
Guido van Rossum68468eb2003-02-27 20:14:51 +0000349 return _BoundedSemaphore(*args, **kwargs)
Skip Montanaroe428bb72001-08-20 20:27:58 +0000350
351class _BoundedSemaphore(_Semaphore):
352 """Semaphore that checks that # releases is <= # acquires"""
353 def __init__(self, value=1, verbose=None):
354 _Semaphore.__init__(self, value, verbose)
355 self._initial_value = value
356
357 def release(self):
358 if self._Semaphore__value >= self._initial_value:
359 raise ValueError, "Semaphore released too many times"
360 return _Semaphore.release(self)
361
362
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000363def Event(*args, **kwargs):
Guido van Rossum68468eb2003-02-27 20:14:51 +0000364 return _Event(*args, **kwargs)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000365
366class _Event(_Verbose):
367
368 # After Tim Peters' event class (without is_posted())
369
370 def __init__(self, verbose=None):
371 _Verbose.__init__(self, verbose)
372 self.__cond = Condition(Lock())
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000373 self.__flag = False
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000374
Gregory P. Smith2b79a812011-01-04 01:10:08 +0000375 def _reset_internal_locks(self):
376 # private! called by Thread._reset_internal_locks by _after_fork()
377 self.__cond.__init__()
378
Benjamin Peterson973e6c22008-09-01 23:12:58 +0000379 def isSet(self):
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000380 return self.__flag
381
Benjamin Peterson973e6c22008-09-01 23:12:58 +0000382 is_set = isSet
Benjamin Petersonf4395602008-06-11 17:50:00 +0000383
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000384 def set(self):
Raymond Hettinger70ec29d2008-01-24 18:12:23 +0000385 self.__cond.acquire()
386 try:
Guido van Rossum21b60142002-11-21 21:08:39 +0000387 self.__flag = True
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000388 self.__cond.notify_all()
Raymond Hettinger70ec29d2008-01-24 18:12:23 +0000389 finally:
390 self.__cond.release()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000391
392 def clear(self):
Raymond Hettinger70ec29d2008-01-24 18:12:23 +0000393 self.__cond.acquire()
394 try:
Guido van Rossum21b60142002-11-21 21:08:39 +0000395 self.__flag = False
Raymond Hettinger70ec29d2008-01-24 18:12:23 +0000396 finally:
397 self.__cond.release()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000398
399 def wait(self, timeout=None):
Raymond Hettinger70ec29d2008-01-24 18:12:23 +0000400 self.__cond.acquire()
401 try:
Guido van Rossum21b60142002-11-21 21:08:39 +0000402 if not self.__flag:
403 self.__cond.wait(timeout)
Georg Brandlef660e82009-03-31 20:41:08 +0000404 return self.__flag
Raymond Hettinger70ec29d2008-01-24 18:12:23 +0000405 finally:
406 self.__cond.release()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000407
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000408# Helper to generate new thread names
409_counter = 0
410def _newname(template="Thread-%d"):
411 global _counter
412 _counter = _counter + 1
413 return template % _counter
414
415# Active thread administration
416_active_limbo_lock = _allocate_lock()
Tim Peters711906e2005-01-08 07:30:42 +0000417_active = {} # maps thread id to Thread object
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000418_limbo = {}
419
420
421# Main class for threads
422
423class Thread(_Verbose):
424
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000425 __initialized = False
Brett Cannoncc4e9352004-07-03 03:52:35 +0000426 # Need to store a reference to sys.exc_info for printing
427 # out exceptions when a thread tries to use a global var. during interp.
428 # shutdown and thus raises an exception about trying to perform some
429 # operation on/with a NoneType
430 __exc_info = _sys.exc_info
Jeffrey Yasskin8b9091f2008-03-28 04:11:18 +0000431 # Keep sys.exc_clear too to clear the exception just before
432 # allowing .join() to return.
433 __exc_clear = _sys.exc_clear
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000434
435 def __init__(self, group=None, target=None, name=None,
Georg Brandla4a8b822005-07-15 09:13:21 +0000436 args=(), kwargs=None, verbose=None):
Guido van Rossum5a43e1a1998-06-09 19:04:26 +0000437 assert group is None, "group argument must be None for now"
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000438 _Verbose.__init__(self, verbose)
Georg Brandla4a8b822005-07-15 09:13:21 +0000439 if kwargs is None:
440 kwargs = {}
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000441 self.__target = target
442 self.__name = str(name or _newname())
443 self.__args = args
444 self.__kwargs = kwargs
445 self.__daemonic = self._set_daemon()
Gregory P. Smith8856dda2008-06-01 23:48:47 +0000446 self.__ident = None
Jeffrey Yasskin69e13092008-02-28 06:09:19 +0000447 self.__started = Event()
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000448 self.__stopped = False
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000449 self.__block = Condition(Lock())
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000450 self.__initialized = True
Brett Cannoncc4e9352004-07-03 03:52:35 +0000451 # sys.stderr is not stored in the class like
452 # sys.exc_info since it can be changed between instances
453 self.__stderr = _sys.stderr
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000454
Gregory P. Smith2b79a812011-01-04 01:10:08 +0000455 def _reset_internal_locks(self):
456 # private! Called by _after_fork() to reset our internal locks as
457 # they may be in an invalid state leading to a deadlock or crash.
Gregory P. Smithc8762022011-01-04 18:43:54 +0000458 if hasattr(self, '_Thread__block'): # DummyThread deletes self.__block
459 self.__block.__init__()
Gregory P. Smith2b79a812011-01-04 01:10:08 +0000460 self.__started._reset_internal_locks()
461
462 @property
463 def _block(self):
464 # used by a unittest
465 return self.__block
466
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000467 def _set_daemon(self):
468 # Overridden in _MainThread and _DummyThread
Benjamin Petersoncbae8692008-08-18 17:45:09 +0000469 return current_thread().daemon
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000470
471 def __repr__(self):
472 assert self.__initialized, "Thread.__init__() was not called"
473 status = "initial"
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000474 if self.__started.is_set():
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000475 status = "started"
476 if self.__stopped:
477 status = "stopped"
478 if self.__daemonic:
Gregory P. Smith8856dda2008-06-01 23:48:47 +0000479 status += " daemon"
480 if self.__ident is not None:
481 status += " %s" % self.__ident
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000482 return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status)
483
484 def start(self):
Collin Winter50b79ce2007-06-06 00:17:35 +0000485 if not self.__initialized:
486 raise RuntimeError("thread.__init__() not called")
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000487 if self.__started.is_set():
Senthil Kumaranb02b3112010-04-06 03:23:33 +0000488 raise RuntimeError("threads can only be started once")
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000489 if __debug__:
490 self._note("%s.start(): starting thread", self)
Benjamin Petersonbd9dd312009-03-31 21:06:30 +0000491 with _active_limbo_lock:
492 _limbo[self] = self
Gregory P. Smith613c7a52010-02-28 18:36:09 +0000493 try:
494 _start_new_thread(self.__bootstrap, ())
495 except Exception:
496 with _active_limbo_lock:
497 del _limbo[self]
498 raise
Jeffrey Yasskin69e13092008-02-28 06:09:19 +0000499 self.__started.wait()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000500
501 def run(self):
Jeffrey Yasskina885c152008-02-23 20:40:35 +0000502 try:
503 if self.__target:
504 self.__target(*self.__args, **self.__kwargs)
505 finally:
506 # Avoid a refcycle if the thread is running a function with
507 # an argument that has a member that points to the thread.
508 del self.__target, self.__args, self.__kwargs
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000509
510 def __bootstrap(self):
Guido van Rossum54ec61e2007-08-20 15:18:04 +0000511 # Wrapper around the real bootstrap code that ignores
512 # exceptions during interpreter cleanup. Those typically
513 # happen when a daemon thread wakes up at an unfortunate
514 # moment, finds the world around it destroyed, and raises some
515 # random exception *** while trying to report the exception in
516 # __bootstrap_inner() below ***. Those random exceptions
517 # don't help anybody, and they confuse users, so we suppress
518 # them. We suppress them only when it appears that the world
519 # indeed has already been destroyed, so that exceptions in
520 # __bootstrap_inner() during normal business hours are properly
521 # reported. Also, we only suppress them for daemonic threads;
522 # if a non-daemonic encounters this, something else is wrong.
523 try:
524 self.__bootstrap_inner()
525 except:
526 if self.__daemonic and _sys is None:
527 return
528 raise
529
Benjamin Petersond906ea62009-03-31 21:34:42 +0000530 def _set_ident(self):
531 self.__ident = _get_ident()
532
Guido van Rossum54ec61e2007-08-20 15:18:04 +0000533 def __bootstrap_inner(self):
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000534 try:
Benjamin Petersond906ea62009-03-31 21:34:42 +0000535 self._set_ident()
Jeffrey Yasskin69e13092008-02-28 06:09:19 +0000536 self.__started.set()
Benjamin Petersonbd9dd312009-03-31 21:06:30 +0000537 with _active_limbo_lock:
538 _active[self.__ident] = self
539 del _limbo[self]
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000540 if __debug__:
541 self._note("%s.__bootstrap(): thread started", self)
Jeremy Hyltonbfccb352003-06-29 16:58:41 +0000542
543 if _trace_hook:
544 self._note("%s.__bootstrap(): registering trace hook", self)
545 _sys.settrace(_trace_hook)
546 if _profile_hook:
547 self._note("%s.__bootstrap(): registering profile hook", self)
548 _sys.setprofile(_profile_hook)
Tim Petersd1b108b2003-06-29 17:24:17 +0000549
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000550 try:
551 self.run()
552 except SystemExit:
553 if __debug__:
554 self._note("%s.__bootstrap(): raised SystemExit", self)
555 except:
556 if __debug__:
557 self._note("%s.__bootstrap(): unhandled exception", self)
Brett Cannoncc4e9352004-07-03 03:52:35 +0000558 # If sys.stderr is no more (most likely from interpreter
559 # shutdown) use self.__stderr. Otherwise still use sys (as in
560 # _sys) in case sys.stderr was redefined since the creation of
561 # self.
562 if _sys:
563 _sys.stderr.write("Exception in thread %s:\n%s\n" %
Benjamin Petersonb6a95562008-08-22 20:43:48 +0000564 (self.name, _format_exc()))
Brett Cannoncc4e9352004-07-03 03:52:35 +0000565 else:
566 # Do the best job possible w/o a huge amt. of code to
567 # approximate a traceback (code ideas from
568 # Lib/traceback.py)
569 exc_type, exc_value, exc_tb = self.__exc_info()
570 try:
571 print>>self.__stderr, (
Benjamin Petersonb6a95562008-08-22 20:43:48 +0000572 "Exception in thread " + self.name +
Brett Cannoncc4e9352004-07-03 03:52:35 +0000573 " (most likely raised during interpreter shutdown):")
574 print>>self.__stderr, (
575 "Traceback (most recent call last):")
576 while exc_tb:
577 print>>self.__stderr, (
578 ' File "%s", line %s, in %s' %
579 (exc_tb.tb_frame.f_code.co_filename,
580 exc_tb.tb_lineno,
581 exc_tb.tb_frame.f_code.co_name))
582 exc_tb = exc_tb.tb_next
583 print>>self.__stderr, ("%s: %s" % (exc_type, exc_value))
584 # Make sure that exc_tb gets deleted since it is a memory
585 # hog; deleting everything else is just for thoroughness
586 finally:
587 del exc_type, exc_value, exc_tb
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000588 else:
589 if __debug__:
590 self._note("%s.__bootstrap(): normal return", self)
Jeffrey Yasskin8b9091f2008-03-28 04:11:18 +0000591 finally:
592 # Prevent a race in
593 # test_threading.test_no_refcycle_through_target when
594 # the exception keeps the target alive past when we
595 # assert that it's dead.
Amaury Forgeot d'Arc504a48f2008-03-29 01:41:08 +0000596 self.__exc_clear()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000597 finally:
Gregory P. Smith95cd5c02008-01-22 01:20:42 +0000598 with _active_limbo_lock:
599 self.__stop()
600 try:
601 # We don't call self.__delete() because it also
602 # grabs _active_limbo_lock.
603 del _active[_get_ident()]
604 except:
605 pass
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000606
607 def __stop(self):
Antoine Pitrou52849bf2012-04-19 23:55:01 +0200608 # DummyThreads delete self.__block, but they have no waiters to
609 # notify anyway (join() is forbidden on them).
610 if not hasattr(self, '_Thread__block'):
611 return
Raymond Hettinger70ec29d2008-01-24 18:12:23 +0000612 self.__block.acquire()
613 self.__stopped = True
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000614 self.__block.notify_all()
Raymond Hettinger70ec29d2008-01-24 18:12:23 +0000615 self.__block.release()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000616
617 def __delete(self):
Tim Peters21429932004-07-21 03:36:52 +0000618 "Remove current thread from the dict of currently running threads."
Brett Cannon8b3d92a2004-07-21 02:21:58 +0000619
Tim Peters21429932004-07-21 03:36:52 +0000620 # Notes about running with dummy_thread:
621 #
622 # Must take care to not raise an exception if dummy_thread is being
623 # used (and thus this module is being used as an instance of
624 # dummy_threading). dummy_thread.get_ident() always returns -1 since
625 # there is only one thread if dummy_thread is being used. Thus
626 # len(_active) is always <= 1 here, and any Thread instance created
627 # overwrites the (if any) thread currently registered in _active.
628 #
629 # An instance of _MainThread is always created by 'threading'. This
630 # gets overwritten the instant an instance of Thread is created; both
631 # threads return -1 from dummy_thread.get_ident() and thus have the
632 # same key in the dict. So when the _MainThread instance created by
633 # 'threading' tries to clean itself up when atexit calls this method
634 # it gets a KeyError if another Thread instance was created.
635 #
636 # This all means that KeyError from trying to delete something from
637 # _active if dummy_threading is being used is a red herring. But
638 # since it isn't if dummy_threading is *not* being used then don't
639 # hide the exception.
Brett Cannon8b3d92a2004-07-21 02:21:58 +0000640
Raymond Hettinger70ec29d2008-01-24 18:12:23 +0000641 try:
Amaury Forgeot d'Arcd7a26512008-04-03 23:07:55 +0000642 with _active_limbo_lock:
Brett Cannon8b3d92a2004-07-21 02:21:58 +0000643 del _active[_get_ident()]
Amaury Forgeot d'Arcd7a26512008-04-03 23:07:55 +0000644 # There must not be any python code between the previous line
645 # and after the lock is released. Otherwise a tracing function
646 # could try to acquire the lock again in the same thread, (in
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000647 # current_thread()), and would block.
Amaury Forgeot d'Arcd7a26512008-04-03 23:07:55 +0000648 except KeyError:
649 if 'dummy_threading' not in _sys.modules:
650 raise
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000651
652 def join(self, timeout=None):
Collin Winter50b79ce2007-06-06 00:17:35 +0000653 if not self.__initialized:
654 raise RuntimeError("Thread.__init__() not called")
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000655 if not self.__started.is_set():
Collin Winter50b79ce2007-06-06 00:17:35 +0000656 raise RuntimeError("cannot join thread before it is started")
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000657 if self is current_thread():
Collin Winter50b79ce2007-06-06 00:17:35 +0000658 raise RuntimeError("cannot join current thread")
659
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000660 if __debug__:
661 if not self.__stopped:
662 self._note("%s.join(): waiting until thread stops", self)
Raymond Hettinger70ec29d2008-01-24 18:12:23 +0000663 self.__block.acquire()
664 try:
Brett Cannonad07ff22005-11-23 02:15:50 +0000665 if timeout is None:
666 while not self.__stopped:
667 self.__block.wait()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000668 if __debug__:
669 self._note("%s.join(): thread stopped", self)
Brett Cannonad07ff22005-11-23 02:15:50 +0000670 else:
671 deadline = _time() + timeout
672 while not self.__stopped:
673 delay = deadline - _time()
674 if delay <= 0:
675 if __debug__:
676 self._note("%s.join(): timed out", self)
677 break
678 self.__block.wait(delay)
679 else:
680 if __debug__:
681 self._note("%s.join(): thread stopped", self)
Raymond Hettinger70ec29d2008-01-24 18:12:23 +0000682 finally:
683 self.__block.release()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000684
Benjamin Petersoncbae8692008-08-18 17:45:09 +0000685 @property
686 def name(self):
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000687 assert self.__initialized, "Thread.__init__() not called"
688 return self.__name
689
Benjamin Petersoncbae8692008-08-18 17:45:09 +0000690 @name.setter
691 def name(self, name):
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000692 assert self.__initialized, "Thread.__init__() not called"
693 self.__name = str(name)
694
Benjamin Petersond8a89722008-08-18 16:40:03 +0000695 @property
696 def ident(self):
Gregory P. Smith8856dda2008-06-01 23:48:47 +0000697 assert self.__initialized, "Thread.__init__() not called"
698 return self.__ident
699
Benjamin Peterson973e6c22008-09-01 23:12:58 +0000700 def isAlive(self):
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000701 assert self.__initialized, "Thread.__init__() not called"
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000702 return self.__started.is_set() and not self.__stopped
Tim Petersb90f89a2001-01-15 03:26:36 +0000703
Benjamin Peterson973e6c22008-09-01 23:12:58 +0000704 is_alive = isAlive
Benjamin Peterson6ee1a312008-08-18 21:53:29 +0000705
Benjamin Petersoncbae8692008-08-18 17:45:09 +0000706 @property
707 def daemon(self):
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000708 assert self.__initialized, "Thread.__init__() not called"
709 return self.__daemonic
710
Benjamin Petersoncbae8692008-08-18 17:45:09 +0000711 @daemon.setter
712 def daemon(self, daemonic):
Collin Winter50b79ce2007-06-06 00:17:35 +0000713 if not self.__initialized:
714 raise RuntimeError("Thread.__init__() not called")
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000715 if self.__started.is_set():
Collin Winter50b79ce2007-06-06 00:17:35 +0000716 raise RuntimeError("cannot set daemon status of active thread");
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000717 self.__daemonic = daemonic
718
Benjamin Petersond8106262008-08-18 18:13:17 +0000719 def isDaemon(self):
720 return self.daemon
721
722 def setDaemon(self, daemonic):
723 self.daemon = daemonic
724
725 def getName(self):
726 return self.name
727
728 def setName(self, name):
729 self.name = name
730
Martin v. Löwis44f86962001-09-05 13:44:54 +0000731# The timer class was contributed by Itamar Shtull-Trauring
732
733def Timer(*args, **kwargs):
734 return _Timer(*args, **kwargs)
735
736class _Timer(Thread):
737 """Call a function after a specified number of seconds:
Tim Petersb64bec32001-09-18 02:26:39 +0000738
Martin v. Löwis44f86962001-09-05 13:44:54 +0000739 t = Timer(30.0, f, args=[], kwargs={})
740 t.start()
741 t.cancel() # stop the timer's action if it's still waiting
742 """
Tim Petersb64bec32001-09-18 02:26:39 +0000743
Martin v. Löwis44f86962001-09-05 13:44:54 +0000744 def __init__(self, interval, function, args=[], kwargs={}):
745 Thread.__init__(self)
746 self.interval = interval
747 self.function = function
748 self.args = args
749 self.kwargs = kwargs
750 self.finished = Event()
Tim Petersb64bec32001-09-18 02:26:39 +0000751
Martin v. Löwis44f86962001-09-05 13:44:54 +0000752 def cancel(self):
753 """Stop the timer if it hasn't finished yet"""
754 self.finished.set()
Tim Petersb64bec32001-09-18 02:26:39 +0000755
Martin v. Löwis44f86962001-09-05 13:44:54 +0000756 def run(self):
757 self.finished.wait(self.interval)
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000758 if not self.finished.is_set():
Martin v. Löwis44f86962001-09-05 13:44:54 +0000759 self.function(*self.args, **self.kwargs)
760 self.finished.set()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000761
762# Special thread class to represent the main thread
763# This is garbage collected through an exit handler
764
765class _MainThread(Thread):
766
767 def __init__(self):
768 Thread.__init__(self, name="MainThread")
Jeffrey Yasskin69e13092008-02-28 06:09:19 +0000769 self._Thread__started.set()
Benjamin Petersond906ea62009-03-31 21:34:42 +0000770 self._set_ident()
Benjamin Petersonbd9dd312009-03-31 21:06:30 +0000771 with _active_limbo_lock:
772 _active[_get_ident()] = self
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000773
774 def _set_daemon(self):
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000775 return False
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000776
Martin v. Löwis7b7c9d42007-01-04 21:06:12 +0000777 def _exitfunc(self):
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000778 self._Thread__stop()
779 t = _pickSomeNonDaemonThread()
780 if t:
781 if __debug__:
782 self._note("%s: waiting for other threads", self)
783 while t:
784 t.join()
785 t = _pickSomeNonDaemonThread()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000786 if __debug__:
787 self._note("%s: exiting", self)
788 self._Thread__delete()
789
790def _pickSomeNonDaemonThread():
791 for t in enumerate():
Benjamin Petersoncbae8692008-08-18 17:45:09 +0000792 if not t.daemon and t.is_alive():
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000793 return t
794 return None
795
796
797# Dummy thread class to represent threads not started here.
Tim Peters711906e2005-01-08 07:30:42 +0000798# These aren't garbage collected when they die, nor can they be waited for.
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000799# If they invoke anything in threading.py that calls current_thread(), they
Tim Peters711906e2005-01-08 07:30:42 +0000800# leave an entry in the _active dict forever after.
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000801# Their purpose is to return *something* from current_thread().
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000802# They are marked as daemon threads so we won't wait for them
803# when we exit (conform previous semantics).
804
805class _DummyThread(Thread):
Tim Petersb90f89a2001-01-15 03:26:36 +0000806
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000807 def __init__(self):
808 Thread.__init__(self, name=_newname("Dummy-%d"))
Tim Peters711906e2005-01-08 07:30:42 +0000809
810 # Thread.__block consumes an OS-level locking primitive, which
811 # can never be used by a _DummyThread. Since a _DummyThread
812 # instance is immortal, that's bad, so release this resource.
Brett Cannone6539c42005-01-08 02:43:53 +0000813 del self._Thread__block
Tim Peters711906e2005-01-08 07:30:42 +0000814
Jeffrey Yasskin69e13092008-02-28 06:09:19 +0000815 self._Thread__started.set()
Benjamin Petersond906ea62009-03-31 21:34:42 +0000816 self._set_ident()
Benjamin Petersonbd9dd312009-03-31 21:06:30 +0000817 with _active_limbo_lock:
818 _active[_get_ident()] = self
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000819
820 def _set_daemon(self):
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000821 return True
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000822
Neal Norwitz45bec8c2002-02-19 03:01:36 +0000823 def join(self, timeout=None):
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000824 assert False, "cannot join a dummy thread"
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000825
826
827# Global API functions
828
Benjamin Peterson973e6c22008-09-01 23:12:58 +0000829def currentThread():
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000830 try:
831 return _active[_get_ident()]
832 except KeyError:
Benjamin Peterson0fbcf692008-06-11 17:27:50 +0000833 ##print "current_thread(): no current thread for", _get_ident()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000834 return _DummyThread()
835
Benjamin Peterson973e6c22008-09-01 23:12:58 +0000836current_thread = currentThread
Benjamin Petersonf4395602008-06-11 17:50:00 +0000837
Benjamin Peterson973e6c22008-09-01 23:12:58 +0000838def activeCount():
Benjamin Petersonbd9dd312009-03-31 21:06:30 +0000839 with _active_limbo_lock:
840 return len(_active) + len(_limbo)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000841
Benjamin Peterson973e6c22008-09-01 23:12:58 +0000842active_count = activeCount
Benjamin Petersonf4395602008-06-11 17:50:00 +0000843
Antoine Pitrou99c160b2009-11-05 13:42:29 +0000844def _enumerate():
845 # Same as enumerate(), but without the lock. Internal use only.
846 return _active.values() + _limbo.values()
847
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000848def enumerate():
Benjamin Petersonbd9dd312009-03-31 21:06:30 +0000849 with _active_limbo_lock:
850 return _active.values() + _limbo.values()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000851
Andrew MacIntyre92913322006-06-13 15:04:24 +0000852from thread import stack_size
853
Martin v. Löwis7b7c9d42007-01-04 21:06:12 +0000854# Create the main thread object,
855# and make it available for the interpreter
856# (Py_Main) as threading._shutdown.
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000857
Martin v. Löwis7b7c9d42007-01-04 21:06:12 +0000858_shutdown = _MainThread()._exitfunc
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000859
Jim Fultond15dc062004-07-14 19:11:50 +0000860# get thread-local implementation, either from the thread
861# module, or from the python fallback
862
863try:
864 from thread import _local as local
865except ImportError:
866 from _threading_local import local
867
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000868
Jesse Noller5e62ca42008-07-16 20:03:47 +0000869def _after_fork():
870 # This function is called by Python/ceval.c:PyEval_ReInitThreads which
871 # is called from PyOS_AfterFork. Here we cleanup threading module state
872 # that should not exist after a fork.
873
874 # Reset _active_limbo_lock, in case we forked while the lock was held
875 # by another (non-forked) thread. http://bugs.python.org/issue874900
876 global _active_limbo_lock
877 _active_limbo_lock = _allocate_lock()
878
879 # fork() only copied the current thread; clear references to others.
880 new_active = {}
881 current = current_thread()
882 with _active_limbo_lock:
Antoine Pitrou9fb1aca2008-09-06 23:04:32 +0000883 for thread in _active.itervalues():
Charles-François Natali41616302011-12-18 18:22:24 +0100884 # Any lock/condition variable may be currently locked or in an
885 # invalid state, so we reinitialize them.
886 if hasattr(thread, '_reset_internal_locks'):
887 thread._reset_internal_locks()
Jesse Noller5e62ca42008-07-16 20:03:47 +0000888 if thread is current:
Antoine Pitrou9fb1aca2008-09-06 23:04:32 +0000889 # There is only one active thread. We reset the ident to
890 # its new value since it can have changed.
891 ident = _get_ident()
892 thread._Thread__ident = ident
Jesse Noller5e62ca42008-07-16 20:03:47 +0000893 new_active[ident] = thread
894 else:
895 # All the others are already stopped.
Charles-François Natali41616302011-12-18 18:22:24 +0100896 thread._Thread__stop()
Jesse Noller5e62ca42008-07-16 20:03:47 +0000897
898 _limbo.clear()
899 _active.clear()
900 _active.update(new_active)
901 assert len(_active) == 1
902
903
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000904# Self-test code
905
906def _test():
907
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000908 class BoundedQueue(_Verbose):
909
910 def __init__(self, limit):
911 _Verbose.__init__(self)
912 self.mon = RLock()
913 self.rc = Condition(self.mon)
914 self.wc = Condition(self.mon)
915 self.limit = limit
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000916 self.queue = deque()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000917
918 def put(self, item):
919 self.mon.acquire()
920 while len(self.queue) >= self.limit:
921 self._note("put(%s): queue full", item)
922 self.wc.wait()
923 self.queue.append(item)
924 self._note("put(%s): appended, length now %d",
925 item, len(self.queue))
926 self.rc.notify()
927 self.mon.release()
928
929 def get(self):
930 self.mon.acquire()
931 while not self.queue:
932 self._note("get(): queue empty")
933 self.rc.wait()
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000934 item = self.queue.popleft()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000935 self._note("get(): got %s, %d left", item, len(self.queue))
936 self.wc.notify()
937 self.mon.release()
938 return item
939
940 class ProducerThread(Thread):
941
942 def __init__(self, queue, quota):
943 Thread.__init__(self, name="Producer")
944 self.queue = queue
945 self.quota = quota
946
947 def run(self):
Guido van Rossumb26a1b41998-05-20 17:05:52 +0000948 from random import random
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000949 counter = 0
950 while counter < self.quota:
951 counter = counter + 1
Benjamin Petersoncbae8692008-08-18 17:45:09 +0000952 self.queue.put("%s.%d" % (self.name, counter))
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000953 _sleep(random() * 0.00001)
954
955
956 class ConsumerThread(Thread):
957
958 def __init__(self, queue, count):
959 Thread.__init__(self, name="Consumer")
960 self.queue = queue
961 self.count = count
962
963 def run(self):
964 while self.count > 0:
965 item = self.queue.get()
966 print item
967 self.count = self.count - 1
968
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000969 NP = 3
970 QL = 4
971 NI = 5
972
973 Q = BoundedQueue(QL)
974 P = []
975 for i in range(NP):
976 t = ProducerThread(Q, NI)
Benjamin Petersoncbae8692008-08-18 17:45:09 +0000977 t.name = ("Producer-%d" % (i+1))
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000978 P.append(t)
979 C = ConsumerThread(Q, NI*NP)
980 for t in P:
981 t.start()
982 _sleep(0.000001)
983 C.start()
984 for t in P:
985 t.join()
986 C.join()
987
988if __name__ == '__main__':
989 _test()