blob: 2e6fab9f9b7cc788d861cf660866a74ee0469a4c [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
Fred Drakea8725952002-12-30 23:32:50 +000011from time import time as _time, sleep as _sleep
Neil Schemenauerf607fc52003-11-05 23:03:00 +000012from traceback import format_exc as _format_exc
Raymond Hettinger756b3f32004-01-29 06:37:52 +000013from collections import deque
Guido van Rossum7f5013a1998-04-09 22:01:42 +000014
15# Rename some stuff so "from threading import *" is safe
Guido van Rossumc262a1f2002-12-30 21:59:55 +000016__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
Tim Peters685e6972003-06-29 16:50:06 +000017 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
Jim Fultond15dc062004-07-14 19:11:50 +000018 'Timer', 'setprofile', 'settrace', 'local']
Guido van Rossum7f5013a1998-04-09 22:01:42 +000019
Guido van Rossum7f5013a1998-04-09 22:01:42 +000020_start_new_thread = thread.start_new_thread
21_allocate_lock = thread.allocate_lock
22_get_ident = thread.get_ident
Jeremy Hyltonb5fc7492000-06-01 01:17:17 +000023ThreadError = thread.error
Guido van Rossum7f5013a1998-04-09 22:01:42 +000024del thread
25
Guido van Rossum7f5013a1998-04-09 22:01:42 +000026
Tim Peters59aba122003-07-01 20:01:55 +000027# Debug support (adapted from ihooks.py).
28# All the major classes here derive from _Verbose. We force that to
29# be a new-style class so that all the major classes here are new-style.
30# This helps debugging (type(instance) is more revealing for instances
31# of new-style classes).
Guido van Rossum7f5013a1998-04-09 22:01:42 +000032
Tim Peters0939fac2003-07-01 19:28:44 +000033_VERBOSE = False
Guido van Rossum7f5013a1998-04-09 22:01:42 +000034
35if __debug__:
36
Tim Peters59aba122003-07-01 20:01:55 +000037 class _Verbose(object):
Guido van Rossum7f5013a1998-04-09 22:01:42 +000038
39 def __init__(self, verbose=None):
40 if verbose is None:
41 verbose = _VERBOSE
42 self.__verbose = verbose
43
44 def _note(self, format, *args):
45 if self.__verbose:
46 format = format % args
47 format = "%s: %s\n" % (
48 currentThread().getName(), format)
49 _sys.stderr.write(format)
50
51else:
52 # Disable this when using "python -O"
Tim Peters59aba122003-07-01 20:01:55 +000053 class _Verbose(object):
Guido van Rossum7f5013a1998-04-09 22:01:42 +000054 def __init__(self, verbose=None):
55 pass
56 def _note(self, *args):
57 pass
58
Jeremy Hyltonbfccb352003-06-29 16:58:41 +000059# Support for profile and trace hooks
60
61_profile_hook = None
62_trace_hook = None
63
64def setprofile(func):
65 global _profile_hook
66 _profile_hook = func
Tim Petersd1b108b2003-06-29 17:24:17 +000067
Jeremy Hyltonbfccb352003-06-29 16:58:41 +000068def settrace(func):
69 global _trace_hook
70 _trace_hook = func
Guido van Rossum7f5013a1998-04-09 22:01:42 +000071
72# Synchronization classes
73
74Lock = _allocate_lock
75
76def RLock(*args, **kwargs):
Guido van Rossum68468eb2003-02-27 20:14:51 +000077 return _RLock(*args, **kwargs)
Guido van Rossum7f5013a1998-04-09 22:01:42 +000078
79class _RLock(_Verbose):
Tim Petersb90f89a2001-01-15 03:26:36 +000080
Guido van Rossum7f5013a1998-04-09 22:01:42 +000081 def __init__(self, verbose=None):
82 _Verbose.__init__(self, verbose)
83 self.__block = _allocate_lock()
84 self.__owner = None
85 self.__count = 0
86
87 def __repr__(self):
88 return "<%s(%s, %d)>" % (
89 self.__class__.__name__,
90 self.__owner and self.__owner.getName(),
91 self.__count)
92
93 def acquire(self, blocking=1):
94 me = currentThread()
95 if self.__owner is me:
96 self.__count = self.__count + 1
97 if __debug__:
98 self._note("%s.acquire(%s): recursive success", self, blocking)
99 return 1
100 rc = self.__block.acquire(blocking)
101 if rc:
102 self.__owner = me
103 self.__count = 1
104 if __debug__:
105 self._note("%s.acquire(%s): initial succes", self, blocking)
106 else:
107 if __debug__:
108 self._note("%s.acquire(%s): failure", self, blocking)
109 return rc
110
111 def release(self):
112 me = currentThread()
113 assert self.__owner is me, "release() of un-acquire()d lock"
114 self.__count = count = self.__count - 1
115 if not count:
116 self.__owner = None
117 self.__block.release()
118 if __debug__:
119 self._note("%s.release(): final release", self)
120 else:
121 if __debug__:
122 self._note("%s.release(): non-final release", self)
123
124 # Internal methods used by condition variables
125
126 def _acquire_restore(self, (count, owner)):
127 self.__block.acquire()
128 self.__count = count
129 self.__owner = owner
130 if __debug__:
131 self._note("%s._acquire_restore()", self)
132
133 def _release_save(self):
134 if __debug__:
135 self._note("%s._release_save()", self)
136 count = self.__count
137 self.__count = 0
138 owner = self.__owner
139 self.__owner = None
140 self.__block.release()
141 return (count, owner)
142
143 def _is_owned(self):
144 return self.__owner is currentThread()
145
146
147def Condition(*args, **kwargs):
Guido van Rossum68468eb2003-02-27 20:14:51 +0000148 return _Condition(*args, **kwargs)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000149
150class _Condition(_Verbose):
151
152 def __init__(self, lock=None, verbose=None):
153 _Verbose.__init__(self, verbose)
154 if lock is None:
155 lock = RLock()
156 self.__lock = lock
157 # Export the lock's acquire() and release() methods
158 self.acquire = lock.acquire
159 self.release = lock.release
160 # If the lock defines _release_save() and/or _acquire_restore(),
161 # these override the default implementations (which just call
162 # release() and acquire() on the lock). Ditto for _is_owned().
163 try:
164 self._release_save = lock._release_save
165 except AttributeError:
166 pass
167 try:
168 self._acquire_restore = lock._acquire_restore
169 except AttributeError:
170 pass
171 try:
172 self._is_owned = lock._is_owned
173 except AttributeError:
174 pass
175 self.__waiters = []
176
177 def __repr__(self):
178 return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
179
180 def _release_save(self):
181 self.__lock.release() # No state to save
182
183 def _acquire_restore(self, x):
184 self.__lock.acquire() # Ignore saved state
185
186 def _is_owned(self):
Jeremy Hylton39c12bf2002-08-14 17:46:40 +0000187 # Return True if lock is owned by currentThread.
Jeremy Hyltonaf7fde72002-08-14 17:43:59 +0000188 # This method is called only if __lock doesn't have _is_owned().
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000189 if self.__lock.acquire(0):
190 self.__lock.release()
Tim Petersbc0e9102002-04-04 22:55:58 +0000191 return False
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000192 else:
Tim Petersbc0e9102002-04-04 22:55:58 +0000193 return True
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000194
195 def wait(self, timeout=None):
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000196 assert self._is_owned(), "wait() of un-acquire()d lock"
197 waiter = _allocate_lock()
198 waiter.acquire()
199 self.__waiters.append(waiter)
200 saved_state = self._release_save()
Tim Petersc951bf92001-04-02 20:15:57 +0000201 try: # restore state no matter what (e.g., KeyboardInterrupt)
202 if timeout is None:
203 waiter.acquire()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000204 if __debug__:
Tim Petersc951bf92001-04-02 20:15:57 +0000205 self._note("%s.wait(): got it", self)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000206 else:
Tim Petersa6a4f272001-08-12 00:41:33 +0000207 # Balancing act: We can't afford a pure busy loop, so we
208 # have to sleep; but if we sleep the whole timeout time,
209 # we'll be unresponsive. The scheme here sleeps very
210 # little at first, longer as time goes on, but never longer
211 # than 20 times per second (or the timeout time remaining).
Tim Petersc951bf92001-04-02 20:15:57 +0000212 endtime = _time() + timeout
Tim Petersa6a4f272001-08-12 00:41:33 +0000213 delay = 0.0005 # 500 us -> initial delay of 1 ms
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000214 while True:
Tim Petersc951bf92001-04-02 20:15:57 +0000215 gotit = waiter.acquire(0)
Tim Petersa6a4f272001-08-12 00:41:33 +0000216 if gotit:
Tim Petersc951bf92001-04-02 20:15:57 +0000217 break
Tim Petersa6a4f272001-08-12 00:41:33 +0000218 remaining = endtime - _time()
219 if remaining <= 0:
220 break
221 delay = min(delay * 2, remaining, .05)
Tim Petersc951bf92001-04-02 20:15:57 +0000222 _sleep(delay)
Tim Petersc951bf92001-04-02 20:15:57 +0000223 if not gotit:
224 if __debug__:
225 self._note("%s.wait(%s): timed out", self, timeout)
226 try:
227 self.__waiters.remove(waiter)
228 except ValueError:
229 pass
230 else:
231 if __debug__:
232 self._note("%s.wait(%s): got it", self, timeout)
233 finally:
234 self._acquire_restore(saved_state)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000235
236 def notify(self, n=1):
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000237 assert self._is_owned(), "notify() of un-acquire()d lock"
238 __waiters = self.__waiters
239 waiters = __waiters[:n]
240 if not waiters:
241 if __debug__:
242 self._note("%s.notify(): no waiters", self)
243 return
244 self._note("%s.notify(): notifying %d waiter%s", self, n,
245 n!=1 and "s" or "")
246 for waiter in waiters:
247 waiter.release()
248 try:
249 __waiters.remove(waiter)
250 except ValueError:
251 pass
252
253 def notifyAll(self):
254 self.notify(len(self.__waiters))
255
256
257def Semaphore(*args, **kwargs):
Guido van Rossum68468eb2003-02-27 20:14:51 +0000258 return _Semaphore(*args, **kwargs)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000259
260class _Semaphore(_Verbose):
261
Andrew M. Kuchling39d3bfc2000-02-29 00:10:24 +0000262 # After Tim Peters' semaphore class, but not quite the same (no maximum)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000263
264 def __init__(self, value=1, verbose=None):
265 assert value >= 0, "Semaphore initial value must be >= 0"
266 _Verbose.__init__(self, verbose)
267 self.__cond = Condition(Lock())
268 self.__value = value
269
270 def acquire(self, blocking=1):
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000271 rc = False
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000272 self.__cond.acquire()
273 while self.__value == 0:
274 if not blocking:
275 break
Skip Montanarob446fc72001-08-19 04:25:24 +0000276 if __debug__:
277 self._note("%s.acquire(%s): blocked waiting, value=%s",
278 self, blocking, self.__value)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000279 self.__cond.wait()
280 else:
281 self.__value = self.__value - 1
Skip Montanarob446fc72001-08-19 04:25:24 +0000282 if __debug__:
Skip Montanaroae8454a2001-08-19 05:53:47 +0000283 self._note("%s.acquire: success, value=%s",
284 self, self.__value)
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000285 rc = True
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000286 self.__cond.release()
287 return rc
288
289 def release(self):
290 self.__cond.acquire()
291 self.__value = self.__value + 1
Skip Montanarob446fc72001-08-19 04:25:24 +0000292 if __debug__:
Skip Montanaroae8454a2001-08-19 05:53:47 +0000293 self._note("%s.release: success, value=%s",
294 self, self.__value)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000295 self.__cond.notify()
296 self.__cond.release()
297
298
Skip Montanaroe428bb72001-08-20 20:27:58 +0000299def BoundedSemaphore(*args, **kwargs):
Guido van Rossum68468eb2003-02-27 20:14:51 +0000300 return _BoundedSemaphore(*args, **kwargs)
Skip Montanaroe428bb72001-08-20 20:27:58 +0000301
302class _BoundedSemaphore(_Semaphore):
303 """Semaphore that checks that # releases is <= # acquires"""
304 def __init__(self, value=1, verbose=None):
305 _Semaphore.__init__(self, value, verbose)
306 self._initial_value = value
307
308 def release(self):
309 if self._Semaphore__value >= self._initial_value:
310 raise ValueError, "Semaphore released too many times"
311 return _Semaphore.release(self)
312
313
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000314def Event(*args, **kwargs):
Guido van Rossum68468eb2003-02-27 20:14:51 +0000315 return _Event(*args, **kwargs)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000316
317class _Event(_Verbose):
318
319 # After Tim Peters' event class (without is_posted())
320
321 def __init__(self, verbose=None):
322 _Verbose.__init__(self, verbose)
323 self.__cond = Condition(Lock())
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000324 self.__flag = False
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000325
326 def isSet(self):
327 return self.__flag
328
329 def set(self):
330 self.__cond.acquire()
Guido van Rossum21b60142002-11-21 21:08:39 +0000331 try:
332 self.__flag = True
333 self.__cond.notifyAll()
334 finally:
335 self.__cond.release()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000336
337 def clear(self):
338 self.__cond.acquire()
Guido van Rossum21b60142002-11-21 21:08:39 +0000339 try:
340 self.__flag = False
341 finally:
342 self.__cond.release()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000343
344 def wait(self, timeout=None):
345 self.__cond.acquire()
Guido van Rossum21b60142002-11-21 21:08:39 +0000346 try:
347 if not self.__flag:
348 self.__cond.wait(timeout)
349 finally:
350 self.__cond.release()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000351
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000352# Helper to generate new thread names
353_counter = 0
354def _newname(template="Thread-%d"):
355 global _counter
356 _counter = _counter + 1
357 return template % _counter
358
359# Active thread administration
360_active_limbo_lock = _allocate_lock()
361_active = {}
362_limbo = {}
363
364
365# Main class for threads
366
367class Thread(_Verbose):
368
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000369 __initialized = False
Brett Cannoncc4e9352004-07-03 03:52:35 +0000370 # Need to store a reference to sys.exc_info for printing
371 # out exceptions when a thread tries to use a global var. during interp.
372 # shutdown and thus raises an exception about trying to perform some
373 # operation on/with a NoneType
374 __exc_info = _sys.exc_info
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000375
376 def __init__(self, group=None, target=None, name=None,
377 args=(), kwargs={}, verbose=None):
Guido van Rossum5a43e1a1998-06-09 19:04:26 +0000378 assert group is None, "group argument must be None for now"
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000379 _Verbose.__init__(self, verbose)
380 self.__target = target
381 self.__name = str(name or _newname())
382 self.__args = args
383 self.__kwargs = kwargs
384 self.__daemonic = self._set_daemon()
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000385 self.__started = False
386 self.__stopped = False
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000387 self.__block = Condition(Lock())
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000388 self.__initialized = True
Brett Cannoncc4e9352004-07-03 03:52:35 +0000389 # sys.stderr is not stored in the class like
390 # sys.exc_info since it can be changed between instances
391 self.__stderr = _sys.stderr
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000392
393 def _set_daemon(self):
394 # Overridden in _MainThread and _DummyThread
395 return currentThread().isDaemon()
396
397 def __repr__(self):
398 assert self.__initialized, "Thread.__init__() was not called"
399 status = "initial"
400 if self.__started:
401 status = "started"
402 if self.__stopped:
403 status = "stopped"
404 if self.__daemonic:
405 status = status + " daemon"
406 return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status)
407
408 def start(self):
409 assert self.__initialized, "Thread.__init__() not called"
410 assert not self.__started, "thread already started"
411 if __debug__:
412 self._note("%s.start(): starting thread", self)
413 _active_limbo_lock.acquire()
414 _limbo[self] = self
415 _active_limbo_lock.release()
416 _start_new_thread(self.__bootstrap, ())
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000417 self.__started = True
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000418 _sleep(0.000001) # 1 usec, to let the thread run (Solaris hack)
419
420 def run(self):
421 if self.__target:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000422 self.__target(*self.__args, **self.__kwargs)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000423
424 def __bootstrap(self):
425 try:
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000426 self.__started = True
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000427 _active_limbo_lock.acquire()
428 _active[_get_ident()] = self
429 del _limbo[self]
430 _active_limbo_lock.release()
431 if __debug__:
432 self._note("%s.__bootstrap(): thread started", self)
Jeremy Hyltonbfccb352003-06-29 16:58:41 +0000433
434 if _trace_hook:
435 self._note("%s.__bootstrap(): registering trace hook", self)
436 _sys.settrace(_trace_hook)
437 if _profile_hook:
438 self._note("%s.__bootstrap(): registering profile hook", self)
439 _sys.setprofile(_profile_hook)
Tim Petersd1b108b2003-06-29 17:24:17 +0000440
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000441 try:
442 self.run()
443 except SystemExit:
444 if __debug__:
445 self._note("%s.__bootstrap(): raised SystemExit", self)
446 except:
447 if __debug__:
448 self._note("%s.__bootstrap(): unhandled exception", self)
Brett Cannoncc4e9352004-07-03 03:52:35 +0000449 # If sys.stderr is no more (most likely from interpreter
450 # shutdown) use self.__stderr. Otherwise still use sys (as in
451 # _sys) in case sys.stderr was redefined since the creation of
452 # self.
453 if _sys:
454 _sys.stderr.write("Exception in thread %s:\n%s\n" %
455 (self.getName(), _format_exc()))
456 else:
457 # Do the best job possible w/o a huge amt. of code to
458 # approximate a traceback (code ideas from
459 # Lib/traceback.py)
460 exc_type, exc_value, exc_tb = self.__exc_info()
461 try:
462 print>>self.__stderr, (
463 "Exception in thread " + self.getName() +
464 " (most likely raised during interpreter shutdown):")
465 print>>self.__stderr, (
466 "Traceback (most recent call last):")
467 while exc_tb:
468 print>>self.__stderr, (
469 ' File "%s", line %s, in %s' %
470 (exc_tb.tb_frame.f_code.co_filename,
471 exc_tb.tb_lineno,
472 exc_tb.tb_frame.f_code.co_name))
473 exc_tb = exc_tb.tb_next
474 print>>self.__stderr, ("%s: %s" % (exc_type, exc_value))
475 # Make sure that exc_tb gets deleted since it is a memory
476 # hog; deleting everything else is just for thoroughness
477 finally:
478 del exc_type, exc_value, exc_tb
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000479 else:
480 if __debug__:
481 self._note("%s.__bootstrap(): normal return", self)
482 finally:
483 self.__stop()
Guido van Rossumf21b2aa2001-12-28 22:07:09 +0000484 try:
485 self.__delete()
486 except:
487 pass
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000488
489 def __stop(self):
490 self.__block.acquire()
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000491 self.__stopped = True
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000492 self.__block.notifyAll()
493 self.__block.release()
494
495 def __delete(self):
Brett Cannon8b3d92a2004-07-21 02:21:58 +0000496 """Remove the current thread from the dict of currently running
497 threads.
498
499 Must take care to not raise an exception if dummy_thread is being used
500 (and thus this module is being used as an instance of dummy_threading).
501 Since dummy_thread.get_ident() always returns -1 since there is only one
502 thread if dummy_thread is being used. This means that if any Thread
503 instances are created they will overwrite any other threads registered.
504
505 This is an issue with this method, though, since an instance of
506 _MainThread is always created by 'threading'. This gets overwritten the
507 instant an instance of Thread is created; both threads will have -1 as
508 their value from dummy_thread.get_ident() and thus have the same key in
509 the dict. This means that when the _MainThread instance created by
510 'threading' tries to clean itself up when atexit calls this method it
511 gets a key error if another Thread instance was created since that
512 removed the only thing with the key of -1.
513
514 This all means that KeyError from trying to delete something from
515 _active if dummy_threading is being used is a red herring. But since
516 it isn't if dummy_threading is *not* being used then don't hide the
517 exception. Also don't need to worry about issues from interpreter
518 shutdown and sys not being defined because the call is protected by a
519 blanket try/except block where that could be a problem.
520
521 """
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000522 _active_limbo_lock.acquire()
Brett Cannon8b3d92a2004-07-21 02:21:58 +0000523 if _sys.modules.has_key('dummy_threading'):
524 try:
525 del _active[_get_ident()]
526 except KeyError:
527 pass
528 else:
529 del _active[_get_ident()]
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000530 _active_limbo_lock.release()
531
532 def join(self, timeout=None):
533 assert self.__initialized, "Thread.__init__() not called"
Guido van Rossum5a43e1a1998-06-09 19:04:26 +0000534 assert self.__started, "cannot join thread before it is started"
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000535 assert self is not currentThread(), "cannot join current thread"
536 if __debug__:
537 if not self.__stopped:
538 self._note("%s.join(): waiting until thread stops", self)
539 self.__block.acquire()
540 if timeout is None:
Guido van Rossum5a43e1a1998-06-09 19:04:26 +0000541 while not self.__stopped:
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000542 self.__block.wait()
543 if __debug__:
544 self._note("%s.join(): thread stopped", self)
545 else:
Guido van Rossumb39e4611998-05-29 17:47:10 +0000546 deadline = _time() + timeout
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000547 while not self.__stopped:
Guido van Rossumb39e4611998-05-29 17:47:10 +0000548 delay = deadline - _time()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000549 if delay <= 0:
550 if __debug__:
551 self._note("%s.join(): timed out", self)
552 break
553 self.__block.wait(delay)
554 else:
555 if __debug__:
556 self._note("%s.join(): thread stopped", self)
557 self.__block.release()
558
559 def getName(self):
560 assert self.__initialized, "Thread.__init__() not called"
561 return self.__name
562
563 def setName(self, name):
564 assert self.__initialized, "Thread.__init__() not called"
565 self.__name = str(name)
566
567 def isAlive(self):
568 assert self.__initialized, "Thread.__init__() not called"
569 return self.__started and not self.__stopped
Tim Petersb90f89a2001-01-15 03:26:36 +0000570
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000571 def isDaemon(self):
572 assert self.__initialized, "Thread.__init__() not called"
573 return self.__daemonic
574
575 def setDaemon(self, daemonic):
576 assert self.__initialized, "Thread.__init__() not called"
577 assert not self.__started, "cannot set daemon status of active thread"
578 self.__daemonic = daemonic
579
Martin v. Löwis44f86962001-09-05 13:44:54 +0000580# The timer class was contributed by Itamar Shtull-Trauring
581
582def Timer(*args, **kwargs):
583 return _Timer(*args, **kwargs)
584
585class _Timer(Thread):
586 """Call a function after a specified number of seconds:
Tim Petersb64bec32001-09-18 02:26:39 +0000587
Martin v. Löwis44f86962001-09-05 13:44:54 +0000588 t = Timer(30.0, f, args=[], kwargs={})
589 t.start()
590 t.cancel() # stop the timer's action if it's still waiting
591 """
Tim Petersb64bec32001-09-18 02:26:39 +0000592
Martin v. Löwis44f86962001-09-05 13:44:54 +0000593 def __init__(self, interval, function, args=[], kwargs={}):
594 Thread.__init__(self)
595 self.interval = interval
596 self.function = function
597 self.args = args
598 self.kwargs = kwargs
599 self.finished = Event()
Tim Petersb64bec32001-09-18 02:26:39 +0000600
Martin v. Löwis44f86962001-09-05 13:44:54 +0000601 def cancel(self):
602 """Stop the timer if it hasn't finished yet"""
603 self.finished.set()
Tim Petersb64bec32001-09-18 02:26:39 +0000604
Martin v. Löwis44f86962001-09-05 13:44:54 +0000605 def run(self):
606 self.finished.wait(self.interval)
607 if not self.finished.isSet():
608 self.function(*self.args, **self.kwargs)
609 self.finished.set()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000610
611# Special thread class to represent the main thread
612# This is garbage collected through an exit handler
613
614class _MainThread(Thread):
615
616 def __init__(self):
617 Thread.__init__(self, name="MainThread")
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000618 self._Thread__started = True
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000619 _active_limbo_lock.acquire()
620 _active[_get_ident()] = self
621 _active_limbo_lock.release()
Fred Drake7b4fc172000-08-18 15:50:54 +0000622 import atexit
623 atexit.register(self.__exitfunc)
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000624
625 def _set_daemon(self):
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000626 return False
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000627
628 def __exitfunc(self):
629 self._Thread__stop()
630 t = _pickSomeNonDaemonThread()
631 if t:
632 if __debug__:
633 self._note("%s: waiting for other threads", self)
634 while t:
635 t.join()
636 t = _pickSomeNonDaemonThread()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000637 if __debug__:
638 self._note("%s: exiting", self)
639 self._Thread__delete()
640
641def _pickSomeNonDaemonThread():
642 for t in enumerate():
643 if not t.isDaemon() and t.isAlive():
644 return t
645 return None
646
647
648# Dummy thread class to represent threads not started here.
649# These aren't garbage collected when they die,
650# nor can they be waited for.
651# Their purpose is to return *something* from currentThread().
652# They are marked as daemon threads so we won't wait for them
653# when we exit (conform previous semantics).
654
655class _DummyThread(Thread):
Tim Petersb90f89a2001-01-15 03:26:36 +0000656
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000657 def __init__(self):
658 Thread.__init__(self, name=_newname("Dummy-%d"))
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000659 self._Thread__started = True
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000660 _active_limbo_lock.acquire()
661 _active[_get_ident()] = self
662 _active_limbo_lock.release()
663
664 def _set_daemon(self):
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000665 return True
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000666
Neal Norwitz45bec8c2002-02-19 03:01:36 +0000667 def join(self, timeout=None):
Guido van Rossum8ca162f2002-04-07 06:36:23 +0000668 assert False, "cannot join a dummy thread"
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000669
670
671# Global API functions
672
673def currentThread():
674 try:
675 return _active[_get_ident()]
676 except KeyError:
Guido van Rossum5080b332000-12-15 20:08:39 +0000677 ##print "currentThread(): no current thread for", _get_ident()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000678 return _DummyThread()
679
680def activeCount():
681 _active_limbo_lock.acquire()
682 count = len(_active) + len(_limbo)
683 _active_limbo_lock.release()
684 return count
685
686def enumerate():
687 _active_limbo_lock.acquire()
688 active = _active.values() + _limbo.values()
689 _active_limbo_lock.release()
690 return active
691
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000692# Create the main thread object
693
694_MainThread()
695
Jim Fultond15dc062004-07-14 19:11:50 +0000696# get thread-local implementation, either from the thread
697# module, or from the python fallback
698
699try:
700 from thread import _local as local
701except ImportError:
702 from _threading_local import local
703
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000704
705# Self-test code
706
707def _test():
708
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000709 class BoundedQueue(_Verbose):
710
711 def __init__(self, limit):
712 _Verbose.__init__(self)
713 self.mon = RLock()
714 self.rc = Condition(self.mon)
715 self.wc = Condition(self.mon)
716 self.limit = limit
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000717 self.queue = deque()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000718
719 def put(self, item):
720 self.mon.acquire()
721 while len(self.queue) >= self.limit:
722 self._note("put(%s): queue full", item)
723 self.wc.wait()
724 self.queue.append(item)
725 self._note("put(%s): appended, length now %d",
726 item, len(self.queue))
727 self.rc.notify()
728 self.mon.release()
729
730 def get(self):
731 self.mon.acquire()
732 while not self.queue:
733 self._note("get(): queue empty")
734 self.rc.wait()
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000735 item = self.queue.popleft()
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000736 self._note("get(): got %s, %d left", item, len(self.queue))
737 self.wc.notify()
738 self.mon.release()
739 return item
740
741 class ProducerThread(Thread):
742
743 def __init__(self, queue, quota):
744 Thread.__init__(self, name="Producer")
745 self.queue = queue
746 self.quota = quota
747
748 def run(self):
Guido van Rossumb26a1b41998-05-20 17:05:52 +0000749 from random import random
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000750 counter = 0
751 while counter < self.quota:
752 counter = counter + 1
753 self.queue.put("%s.%d" % (self.getName(), counter))
754 _sleep(random() * 0.00001)
755
756
757 class ConsumerThread(Thread):
758
759 def __init__(self, queue, count):
760 Thread.__init__(self, name="Consumer")
761 self.queue = queue
762 self.count = count
763
764 def run(self):
765 while self.count > 0:
766 item = self.queue.get()
767 print item
768 self.count = self.count - 1
769
Guido van Rossum7f5013a1998-04-09 22:01:42 +0000770 NP = 3
771 QL = 4
772 NI = 5
773
774 Q = BoundedQueue(QL)
775 P = []
776 for i in range(NP):
777 t = ProducerThread(Q, NI)
778 t.setName("Producer-%d" % (i+1))
779 P.append(t)
780 C = ConsumerThread(Q, NI*NP)
781 for t in P:
782 t.start()
783 _sleep(0.000001)
784 C.start()
785 for t in P:
786 t.join()
787 C.join()
788
789if __name__ == '__main__':
790 _test()