/Lib/threading.py
Python | 1001 lines | 1001 code | 0 blank | 0 comment | 13 complexity | 94436e7630f60b5d787cfde63ada9707 MD5 | raw file
1"""Thread module emulating a subset of Java's threading model.""" 2 3import sys as _sys 4 5try: 6 import thread 7except ImportError: 8 del _sys.modules[__name__] 9 raise 10 11import warnings 12 13from functools import wraps 14from time import time as _time, sleep as _sleep 15from traceback import format_exc as _format_exc 16from collections import deque 17 18# Note regarding PEP 8 compliant aliases 19# This threading model was originally inspired by Java, and inherited 20# the convention of camelCase function and method names from that 21# language. While those names are not in any imminent danger of being 22# deprecated, starting with Python 2.6, the module now provides a 23# PEP 8 compliant alias for any such method name. 24# Using the new PEP 8 compliant names also facilitates substitution 25# with the multiprocessing module, which doesn't provide the old 26# Java inspired names. 27 28 29# Rename some stuff so "from threading import *" is safe 30__all__ = ['activeCount', 'active_count', 'Condition', 'currentThread', 31 'current_thread', 'enumerate', 'Event', 32 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 33 'Timer', 'setprofile', 'settrace', 'local', 'stack_size'] 34 35_start_new_thread = thread.start_new_thread 36_allocate_lock = thread.allocate_lock 37_get_ident = thread.get_ident 38ThreadError = thread.error 39del thread 40 41 42# sys.exc_clear is used to work around the fact that except blocks 43# don't fully clear the exception until 3.0. 44warnings.filterwarnings('ignore', category=DeprecationWarning, 45 module='threading', message='sys.exc_clear') 46 47# Debug support (adapted from ihooks.py). 48# All the major classes here derive from _Verbose. We force that to 49# be a new-style class so that all the major classes here are new-style. 50# This helps debugging (type(instance) is more revealing for instances 51# of new-style classes). 52 53_VERBOSE = False 54 55if __debug__: 56 57 class _Verbose(object): 58 59 def __init__(self, verbose=None): 60 if verbose is None: 61 verbose = _VERBOSE 62 self.__verbose = verbose 63 64 def _note(self, format, *args): 65 if self.__verbose: 66 format = format % args 67 format = "%s: %s\n" % ( 68 current_thread().name, format) 69 _sys.stderr.write(format) 70 71else: 72 # Disable this when using "python -O" 73 class _Verbose(object): 74 def __init__(self, verbose=None): 75 pass 76 def _note(self, *args): 77 pass 78 79# Support for profile and trace hooks 80 81_profile_hook = None 82_trace_hook = None 83 84def setprofile(func): 85 global _profile_hook 86 _profile_hook = func 87 88def settrace(func): 89 global _trace_hook 90 _trace_hook = func 91 92# Synchronization classes 93 94Lock = _allocate_lock 95 96def RLock(*args, **kwargs): 97 return _RLock(*args, **kwargs) 98 99class _RLock(_Verbose): 100 101 def __init__(self, verbose=None): 102 _Verbose.__init__(self, verbose) 103 self.__block = _allocate_lock() 104 self.__owner = None 105 self.__count = 0 106 107 def __repr__(self): 108 owner = self.__owner 109 return "<%s(%s, %d)>" % ( 110 self.__class__.__name__, 111 owner and owner.name, 112 self.__count) 113 114 def acquire(self, blocking=1): 115 me = current_thread() 116 if self.__owner is me: 117 self.__count = self.__count + 1 118 if __debug__: 119 self._note("%s.acquire(%s): recursive success", self, blocking) 120 return 1 121 rc = self.__block.acquire(blocking) 122 if rc: 123 self.__owner = me 124 self.__count = 1 125 if __debug__: 126 self._note("%s.acquire(%s): initial success", self, blocking) 127 else: 128 if __debug__: 129 self._note("%s.acquire(%s): failure", self, blocking) 130 return rc 131 132 __enter__ = acquire 133 134 def release(self): 135 if self.__owner is not current_thread(): 136 raise RuntimeError("cannot release un-aquired lock") 137 self.__count = count = self.__count - 1 138 if not count: 139 self.__owner = None 140 self.__block.release() 141 if __debug__: 142 self._note("%s.release(): final release", self) 143 else: 144 if __debug__: 145 self._note("%s.release(): non-final release", self) 146 147 def __exit__(self, t, v, tb): 148 self.release() 149 150 # Internal methods used by condition variables 151 152 def _acquire_restore(self, count_owner): 153 count, owner = count_owner 154 self.__block.acquire() 155 self.__count = count 156 self.__owner = owner 157 if __debug__: 158 self._note("%s._acquire_restore()", self) 159 160 def _release_save(self): 161 if __debug__: 162 self._note("%s._release_save()", self) 163 count = self.__count 164 self.__count = 0 165 owner = self.__owner 166 self.__owner = None 167 self.__block.release() 168 return (count, owner) 169 170 def _is_owned(self): 171 return self.__owner is current_thread() 172 173 174def Condition(*args, **kwargs): 175 return _Condition(*args, **kwargs) 176 177class _Condition(_Verbose): 178 179 def __init__(self, lock=None, verbose=None): 180 _Verbose.__init__(self, verbose) 181 if lock is None: 182 lock = RLock() 183 self.__lock = lock 184 # Export the lock's acquire() and release() methods 185 self.acquire = lock.acquire 186 self.release = lock.release 187 # If the lock defines _release_save() and/or _acquire_restore(), 188 # these override the default implementations (which just call 189 # release() and acquire() on the lock). Ditto for _is_owned(). 190 try: 191 self._release_save = lock._release_save 192 except AttributeError: 193 pass 194 try: 195 self._acquire_restore = lock._acquire_restore 196 except AttributeError: 197 pass 198 try: 199 self._is_owned = lock._is_owned 200 except AttributeError: 201 pass 202 self.__waiters = [] 203 204 def __enter__(self): 205 return self.__lock.__enter__() 206 207 def __exit__(self, *args): 208 return self.__lock.__exit__(*args) 209 210 def __repr__(self): 211 return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters)) 212 213 def _release_save(self): 214 self.__lock.release() # No state to save 215 216 def _acquire_restore(self, x): 217 self.__lock.acquire() # Ignore saved state 218 219 def _is_owned(self): 220 # Return True if lock is owned by current_thread. 221 # This method is called only if __lock doesn't have _is_owned(). 222 if self.__lock.acquire(0): 223 self.__lock.release() 224 return False 225 else: 226 return True 227 228 def _reset_after_fork(self, lock=None): 229 """Throw away the old lock and replace it with this one.""" 230 if lock is None: 231 lock = Lock() 232 self.__lock = lock 233 # Reset these exported bound methods. If we don't do this, these 234 # bound methods will still refer to the old lock. 235 self.acquire = lock.acquire 236 self.release = lock.release 237 # Any thread that may have been waiting on this condition no longer 238 # exists after the fork. Even though we know the waiter locks must be 239 # in the acquired state, attempting to release these locks is dangerous 240 # on some platforms, such as OS X. 241 self.__waiters = [] 242 243 def wait(self, timeout=None): 244 if not self._is_owned(): 245 raise RuntimeError("cannot wait on un-aquired lock") 246 waiter = _allocate_lock() 247 waiter.acquire() 248 self.__waiters.append(waiter) 249 saved_state = self._release_save() 250 try: # restore state no matter what (e.g., KeyboardInterrupt) 251 if timeout is None: 252 waiter.acquire() 253 if __debug__: 254 self._note("%s.wait(): got it", self) 255 else: 256 # Balancing act: We can't afford a pure busy loop, so we 257 # have to sleep; but if we sleep the whole timeout time, 258 # we'll be unresponsive. The scheme here sleeps very 259 # little at first, longer as time goes on, but never longer 260 # than 20 times per second (or the timeout time remaining). 261 endtime = _time() + timeout 262 delay = 0.0005 # 500 us -> initial delay of 1 ms 263 while True: 264 gotit = waiter.acquire(0) 265 if gotit: 266 break 267 remaining = endtime - _time() 268 if remaining <= 0: 269 break 270 delay = min(delay * 2, remaining, .05) 271 _sleep(delay) 272 if not gotit: 273 if __debug__: 274 self._note("%s.wait(%s): timed out", self, timeout) 275 try: 276 self.__waiters.remove(waiter) 277 except ValueError: 278 pass 279 else: 280 if __debug__: 281 self._note("%s.wait(%s): got it", self, timeout) 282 finally: 283 self._acquire_restore(saved_state) 284 285 def notify(self, n=1): 286 if not self._is_owned(): 287 raise RuntimeError("cannot notify on un-aquired lock") 288 __waiters = self.__waiters 289 waiters = __waiters[:n] 290 if not waiters: 291 if __debug__: 292 self._note("%s.notify(): no waiters", self) 293 return 294 self._note("%s.notify(): notifying %d waiter%s", self, n, 295 n!=1 and "s" or "") 296 for waiter in waiters: 297 waiter.release() 298 try: 299 __waiters.remove(waiter) 300 except ValueError: 301 pass 302 303 def notifyAll(self): 304 self.notify(len(self.__waiters)) 305 306 notify_all = notifyAll 307 308 309def Semaphore(*args, **kwargs): 310 return _Semaphore(*args, **kwargs) 311 312class _Semaphore(_Verbose): 313 314 # After Tim Peters' semaphore class, but not quite the same (no maximum) 315 316 def __init__(self, value=1, verbose=None): 317 if value < 0: 318 raise ValueError("semaphore initial value must be >= 0") 319 _Verbose.__init__(self, verbose) 320 self.__cond = Condition(Lock()) 321 self.__value = value 322 323 def acquire(self, blocking=1): 324 rc = False 325 self.__cond.acquire() 326 while self.__value == 0: 327 if not blocking: 328 break 329 if __debug__: 330 self._note("%s.acquire(%s): blocked waiting, value=%s", 331 self, blocking, self.__value) 332 self.__cond.wait() 333 else: 334 self.__value = self.__value - 1 335 if __debug__: 336 self._note("%s.acquire: success, value=%s", 337 self, self.__value) 338 rc = True 339 self.__cond.release() 340 return rc 341 342 __enter__ = acquire 343 344 def release(self): 345 self.__cond.acquire() 346 self.__value = self.__value + 1 347 if __debug__: 348 self._note("%s.release: success, value=%s", 349 self, self.__value) 350 self.__cond.notify() 351 self.__cond.release() 352 353 def __exit__(self, t, v, tb): 354 self.release() 355 356 357def BoundedSemaphore(*args, **kwargs): 358 return _BoundedSemaphore(*args, **kwargs) 359 360class _BoundedSemaphore(_Semaphore): 361 """Semaphore that checks that # releases is <= # acquires""" 362 def __init__(self, value=1, verbose=None): 363 _Semaphore.__init__(self, value, verbose) 364 self._initial_value = value 365 366 def release(self): 367 if self._Semaphore__value >= self._initial_value: 368 raise ValueError, "Semaphore released too many times" 369 return _Semaphore.release(self) 370 371 372def Event(*args, **kwargs): 373 return _Event(*args, **kwargs) 374 375class _Event(_Verbose): 376 377 # After Tim Peters' event class (without is_posted()) 378 379 def __init__(self, verbose=None): 380 _Verbose.__init__(self, verbose) 381 self.__cond = Condition(Lock()) 382 self.__flag = False 383 384 def isSet(self): 385 return self.__flag 386 387 is_set = isSet 388 389 def set(self): 390 self.__cond.acquire() 391 try: 392 self.__flag = True 393 self.__cond.notify_all() 394 finally: 395 self.__cond.release() 396 397 def clear(self): 398 self.__cond.acquire() 399 try: 400 self.__flag = False 401 finally: 402 self.__cond.release() 403 404 def wait(self, timeout=None): 405 self.__cond.acquire() 406 try: 407 if not self.__flag: 408 self.__cond.wait(timeout) 409 finally: 410 self.__cond.release() 411 412# Helper to generate new thread names 413_counter = 0 414def _newname(template="Thread-%d"): 415 global _counter 416 _counter = _counter + 1 417 return template % _counter 418 419# Active thread administration 420_active_limbo_lock = _allocate_lock() 421_active = {} # maps thread id to Thread object 422_limbo = {} 423 424 425# Main class for threads 426 427class Thread(_Verbose): 428 429 __initialized = False 430 # Need to store a reference to sys.exc_info for printing 431 # out exceptions when a thread tries to use a global var. during interp. 432 # shutdown and thus raises an exception about trying to perform some 433 # operation on/with a NoneType 434 __exc_info = _sys.exc_info 435 # Keep sys.exc_clear too to clear the exception just before 436 # allowing .join() to return. 437 __exc_clear = _sys.exc_clear 438 439 def __init__(self, group=None, target=None, name=None, 440 args=(), kwargs=None, verbose=None): 441 assert group is None, "group argument must be None for now" 442 _Verbose.__init__(self, verbose) 443 if kwargs is None: 444 kwargs = {} 445 self.__target = target 446 self.__name = str(name or _newname()) 447 self.__args = args 448 self.__kwargs = kwargs 449 self.__daemonic = self._set_daemon() 450 self.__ident = None 451 self.__started = Event() 452 self.__stopped = False 453 self.__block = Condition(Lock()) 454 self.__initialized = True 455 # sys.stderr is not stored in the class like 456 # sys.exc_info since it can be changed between instances 457 self.__stderr = _sys.stderr 458 459 def _set_daemon(self): 460 # Overridden in _MainThread and _DummyThread 461 return current_thread().daemon 462 463 def __repr__(self): 464 assert self.__initialized, "Thread.__init__() was not called" 465 status = "initial" 466 if self.__started.is_set(): 467 status = "started" 468 if self.__stopped: 469 status = "stopped" 470 if self.__daemonic: 471 status += " daemon" 472 if self.__ident is not None: 473 status += " %s" % self.__ident 474 return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status) 475 476 def start(self): 477 if not self.__initialized: 478 raise RuntimeError("thread.__init__() not called") 479 if self.__started.is_set(): 480 raise RuntimeError("thread already started") 481 if __debug__: 482 self._note("%s.start(): starting thread", self) 483 _active_limbo_lock.acquire() 484 _limbo[self] = self 485 _active_limbo_lock.release() 486 _start_new_thread(self.__bootstrap, ()) 487 self.__started.wait() 488 489 def run(self): 490 try: 491 if self.__target: 492 self.__target(*self.__args, **self.__kwargs) 493 finally: 494 # Avoid a refcycle if the thread is running a function with 495 # an argument that has a member that points to the thread. 496 del self.__target, self.__args, self.__kwargs 497 498 def __bootstrap(self): 499 # Wrapper around the real bootstrap code that ignores 500 # exceptions during interpreter cleanup. Those typically 501 # happen when a daemon thread wakes up at an unfortunate 502 # moment, finds the world around it destroyed, and raises some 503 # random exception *** while trying to report the exception in 504 # __bootstrap_inner() below ***. Those random exceptions 505 # don't help anybody, and they confuse users, so we suppress 506 # them. We suppress them only when it appears that the world 507 # indeed has already been destroyed, so that exceptions in 508 # __bootstrap_inner() during normal business hours are properly 509 # reported. Also, we only suppress them for daemonic threads; 510 # if a non-daemonic encounters this, something else is wrong. 511 try: 512 self.__bootstrap_inner() 513 except: 514 if self.__daemonic and _sys is None: 515 return 516 raise 517 518 def _set_ident(self): 519 self.__ident = _get_ident() 520 521 def __bootstrap_inner(self): 522 try: 523 self._set_ident() 524 self.__started.set() 525 _active_limbo_lock.acquire() 526 _active[self.__ident] = self 527 del _limbo[self] 528 _active_limbo_lock.release() 529 if __debug__: 530 self._note("%s.__bootstrap(): thread started", self) 531 532 if _trace_hook: 533 self._note("%s.__bootstrap(): registering trace hook", self) 534 _sys.settrace(_trace_hook) 535 if _profile_hook: 536 self._note("%s.__bootstrap(): registering profile hook", self) 537 _sys.setprofile(_profile_hook) 538 539 try: 540 self.run() 541 except SystemExit: 542 if __debug__: 543 self._note("%s.__bootstrap(): raised SystemExit", self) 544 except: 545 if __debug__: 546 self._note("%s.__bootstrap(): unhandled exception", self) 547 # If sys.stderr is no more (most likely from interpreter 548 # shutdown) use self.__stderr. Otherwise still use sys (as in 549 # _sys) in case sys.stderr was redefined since the creation of 550 # self. 551 if _sys: 552 _sys.stderr.write("Exception in thread %s:\n%s\n" % 553 (self.name, _format_exc())) 554 else: 555 # Do the best job possible w/o a huge amt. of code to 556 # approximate a traceback (code ideas from 557 # Lib/traceback.py) 558 exc_type, exc_value, exc_tb = self.__exc_info() 559 try: 560 print>>self.__stderr, ( 561 "Exception in thread " + self.name + 562 " (most likely raised during interpreter shutdown):") 563 print>>self.__stderr, ( 564 "Traceback (most recent call last):") 565 while exc_tb: 566 print>>self.__stderr, ( 567 ' File "%s", line %s, in %s' % 568 (exc_tb.tb_frame.f_code.co_filename, 569 exc_tb.tb_lineno, 570 exc_tb.tb_frame.f_code.co_name)) 571 exc_tb = exc_tb.tb_next 572 print>>self.__stderr, ("%s: %s" % (exc_type, exc_value)) 573 # Make sure that exc_tb gets deleted since it is a memory 574 # hog; deleting everything else is just for thoroughness 575 finally: 576 del exc_type, exc_value, exc_tb 577 else: 578 if __debug__: 579 self._note("%s.__bootstrap(): normal return", self) 580 finally: 581 # Prevent a race in 582 # test_threading.test_no_refcycle_through_target when 583 # the exception keeps the target alive past when we 584 # assert that it's dead. 585 self.__exc_clear() 586 finally: 587 with _active_limbo_lock: 588 self.__stop() 589 try: 590 # We don't call self.__delete() because it also 591 # grabs _active_limbo_lock. 592 del _active[_get_ident()] 593 except: 594 pass 595 596 def __stop(self): 597 self.__block.acquire() 598 self.__stopped = True 599 self.__block.notify_all() 600 self.__block.release() 601 602 def __delete(self): 603 "Remove current thread from the dict of currently running threads." 604 605 # Notes about running with dummy_thread: 606 # 607 # Must take care to not raise an exception if dummy_thread is being 608 # used (and thus this module is being used as an instance of 609 # dummy_threading). dummy_thread.get_ident() always returns -1 since 610 # there is only one thread if dummy_thread is being used. Thus 611 # len(_active) is always <= 1 here, and any Thread instance created 612 # overwrites the (if any) thread currently registered in _active. 613 # 614 # An instance of _MainThread is always created by 'threading'. This 615 # gets overwritten the instant an instance of Thread is created; both 616 # threads return -1 from dummy_thread.get_ident() and thus have the 617 # same key in the dict. So when the _MainThread instance created by 618 # 'threading' tries to clean itself up when atexit calls this method 619 # it gets a KeyError if another Thread instance was created. 620 # 621 # This all means that KeyError from trying to delete something from 622 # _active if dummy_threading is being used is a red herring. But 623 # since it isn't if dummy_threading is *not* being used then don't 624 # hide the exception. 625 626 try: 627 with _active_limbo_lock: 628 del _active[_get_ident()] 629 # There must not be any python code between the previous line 630 # and after the lock is released. Otherwise a tracing function 631 # could try to acquire the lock again in the same thread, (in 632 # current_thread()), and would block. 633 except KeyError: 634 if 'dummy_threading' not in _sys.modules: 635 raise 636 637 def join(self, timeout=None): 638 if not self.__initialized: 639 raise RuntimeError("Thread.__init__() not called") 640 if not self.__started.is_set(): 641 raise RuntimeError("cannot join thread before it is started") 642 if self is current_thread(): 643 raise RuntimeError("cannot join current thread") 644 645 if __debug__: 646 if not self.__stopped: 647 self._note("%s.join(): waiting until thread stops", self) 648 self.__block.acquire() 649 try: 650 if timeout is None: 651 while not self.__stopped: 652 self.__block.wait() 653 if __debug__: 654 self._note("%s.join(): thread stopped", self) 655 else: 656 deadline = _time() + timeout 657 while not self.__stopped: 658 delay = deadline - _time() 659 if delay <= 0: 660 if __debug__: 661 self._note("%s.join(): timed out", self) 662 break 663 self.__block.wait(delay) 664 else: 665 if __debug__: 666 self._note("%s.join(): thread stopped", self) 667 finally: 668 self.__block.release() 669 670 @property 671 def name(self): 672 assert self.__initialized, "Thread.__init__() not called" 673 return self.__name 674 675 @name.setter 676 def name(self, name): 677 assert self.__initialized, "Thread.__init__() not called" 678 self.__name = str(name) 679 680 @property 681 def ident(self): 682 assert self.__initialized, "Thread.__init__() not called" 683 return self.__ident 684 685 def isAlive(self): 686 assert self.__initialized, "Thread.__init__() not called" 687 return self.__started.is_set() and not self.__stopped 688 689 is_alive = isAlive 690 691 @property 692 def daemon(self): 693 assert self.__initialized, "Thread.__init__() not called" 694 return self.__daemonic 695 696 @daemon.setter 697 def daemon(self, daemonic): 698 if not self.__initialized: 699 raise RuntimeError("Thread.__init__() not called") 700 if self.__started.is_set(): 701 raise RuntimeError("cannot set daemon status of active thread"); 702 self.__daemonic = daemonic 703 704 def isDaemon(self): 705 return self.daemon 706 707 def setDaemon(self, daemonic): 708 self.daemon = daemonic 709 710 def getName(self): 711 return self.name 712 713 def setName(self, name): 714 self.name = name 715 716# The timer class was contributed by Itamar Shtull-Trauring 717 718def Timer(*args, **kwargs): 719 return _Timer(*args, **kwargs) 720 721class _Timer(Thread): 722 """Call a function after a specified number of seconds: 723 724 t = Timer(30.0, f, args=[], kwargs={}) 725 t.start() 726 t.cancel() # stop the timer's action if it's still waiting 727 """ 728 729 def __init__(self, interval, function, args=[], kwargs={}): 730 Thread.__init__(self) 731 self.interval = interval 732 self.function = function 733 self.args = args 734 self.kwargs = kwargs 735 self.finished = Event() 736 737 def cancel(self): 738 """Stop the timer if it hasn't finished yet""" 739 self.finished.set() 740 741 def run(self): 742 self.finished.wait(self.interval) 743 if not self.finished.is_set(): 744 self.function(*self.args, **self.kwargs) 745 self.finished.set() 746 747# Special thread class to represent the main thread 748# This is garbage collected through an exit handler 749 750class _MainThread(Thread): 751 752 def __init__(self): 753 Thread.__init__(self, name="MainThread") 754 self._Thread__started.set() 755 self._set_ident() 756 _active_limbo_lock.acquire() 757 _active[_get_ident()] = self 758 _active_limbo_lock.release() 759 760 def _set_daemon(self): 761 return False 762 763def _pickSomeNonDaemonThread(): 764 for t in enumerate(): 765 if not t.daemon and t.is_alive(): 766 return t 767 return None 768 769 770# Dummy thread class to represent threads not started here. 771# These aren't garbage collected when they die, nor can they be waited for. 772# If they invoke anything in threading.py that calls current_thread(), they 773# leave an entry in the _active dict forever after. 774# Their purpose is to return *something* from current_thread(). 775# They are marked as daemon threads so we won't wait for them 776# when we exit (conform previous semantics). 777 778class _DummyThread(Thread): 779 780 def __init__(self): 781 Thread.__init__(self, name=_newname("Dummy-%d")) 782 783 # Thread.__block consumes an OS-level locking primitive, which 784 # can never be used by a _DummyThread. Since a _DummyThread 785 # instance is immortal, that's bad, so release this resource. 786 del self._Thread__block 787 788 self._Thread__started.set() 789 self._set_ident() 790 _active_limbo_lock.acquire() 791 _active[_get_ident()] = self 792 _active_limbo_lock.release() 793 794 def _set_daemon(self): 795 return True 796 797 def join(self, timeout=None): 798 assert False, "cannot join a dummy thread" 799 800 801# Global API functions 802 803def currentThread(): 804 try: 805 return _active[_get_ident()] 806 except KeyError: 807 ##print "current_thread(): no current thread for", _get_ident() 808 return _DummyThread() 809 810current_thread = currentThread 811 812def activeCount(): 813 _active_limbo_lock.acquire() 814 count = len(_active) + len(_limbo) 815 _active_limbo_lock.release() 816 return count 817 818active_count = activeCount 819 820def enumerate(): 821 _active_limbo_lock.acquire() 822 active = _active.values() + _limbo.values() 823 _active_limbo_lock.release() 824 return active 825 826from thread import stack_size 827 828# Create the main thread object and record it's id. This puts it into the 829# active threads dictionary. This assumes that the all threads are created via 830# the threading module. If the program uses the thread module to spawn a 831# thread that imports threading, we'll choose the wrong main thread. 832_MainThread() 833 834main_thread_id = _get_ident() 835 836def _shutdown(): 837 """Shutdown handler that waits for all non-daemon threads to exit. 838 839 This is called from the main thread during shut down. 840 """ 841 # If this thread isn't in the _active dict, then it's because we forked 842 # from a spanwed thread. In that case, because the main thread of the child 843 # process was originally a spawned thread, it will have already removed 844 # itself from the active dict by returning through __bootstrap_inner. 845 # Therefore we don't stop and delete it. 846 ident = _get_ident() 847 assert ident == main_thread_id, \ 848 "Shutdown handler called from non-main thread!" 849 main_thread = _active.get(ident, None) 850 if main_thread: 851 main_thread._Thread__stop() 852 t = _pickSomeNonDaemonThread() 853 if t and main_thread: 854 if __debug__: 855 main_thread._note("%s: waiting for other threads", main_thread) 856 while t: 857 t.join() 858 t = _pickSomeNonDaemonThread() 859 if __debug__ and main_thread: 860 main_thread._note("%s: exiting", main_thread) 861 if main_thread: 862 main_thread._Thread__delete() 863 864 865# get thread-local implementation, either from the thread 866# module, or from the python fallback 867 868try: 869 from thread import _local as local 870except ImportError: 871 from _threading_local import local 872 873 874def _after_fork(): 875 # This function is called by Python/eval.cc:PyEval_ReInitThreads which 876 # is called from PyOS_AfterFork. Here we cleanup threading module state 877 # that should not exist after a fork. 878 879 # Reset _active_limbo_lock, in case we forked while the lock was held 880 # by another (non-forked) thread. http://bugs.python.org/issue874900 881 global _active_limbo_lock 882 _active_limbo_lock = _allocate_lock() 883 884 # fork() only copied the current thread; clear references to others. 885 new_active = {} 886 current = current_thread() 887 with _active_limbo_lock: 888 for thread in _active.itervalues(): 889 if thread is current: 890 # There is only one active thread. We reset the ident to 891 # its new value since it can have changed. 892 ident = _get_ident() 893 thread._Thread__ident = ident 894 # Any locks hanging off of the active thread may be in an 895 # invalid state, so we reset them. 896 thread._Thread__block._reset_after_fork() 897 thread._Thread__started._Event__cond._reset_after_fork() 898 # We also update this global variable so we can keep track of 899 # the new main thread (whichever thread forked). 900 global main_thread_id 901 main_thread_id = ident 902 new_active[ident] = thread 903 else: 904 # All the others are already stopped. 905 # We don't call _Thread__stop() because it tries to acquire 906 # thread._Thread__block which could also have been held while 907 # we forked. 908 thread._Thread__stopped = True 909 910 _limbo.clear() 911 _active.clear() 912 _active.update(new_active) 913 assert len(_active) == 1 914 915 916# Self-test code 917 918def _test(): 919 920 class BoundedQueue(_Verbose): 921 922 def __init__(self, limit): 923 _Verbose.__init__(self) 924 self.mon = RLock() 925 self.rc = Condition(self.mon) 926 self.wc = Condition(self.mon) 927 self.limit = limit 928 self.queue = deque() 929 930 def put(self, item): 931 self.mon.acquire() 932 while len(self.queue) >= self.limit: 933 self._note("put(%s): queue full", item) 934 self.wc.wait() 935 self.queue.append(item) 936 self._note("put(%s): appended, length now %d", 937 item, len(self.queue)) 938 self.rc.notify() 939 self.mon.release() 940 941 def get(self): 942 self.mon.acquire() 943 while not self.queue: 944 self._note("get(): queue empty") 945 self.rc.wait() 946 item = self.queue.popleft() 947 self._note("get(): got %s, %d left", item, len(self.queue)) 948 self.wc.notify() 949 self.mon.release() 950 return item 951 952 class ProducerThread(Thread): 953 954 def __init__(self, queue, quota): 955 Thread.__init__(self, name="Producer") 956 self.queue = queue 957 self.quota = quota 958 959 def run(self): 960 from random import random 961 counter = 0 962 while counter < self.quota: 963 counter = counter + 1 964 self.queue.put("%s.%d" % (self.name, counter)) 965 _sleep(random() * 0.00001) 966 967 968 class ConsumerThread(Thread): 969 970 def __init__(self, queue, count): 971 Thread.__init__(self, name="Consumer") 972 self.queue = queue 973 self.count = count 974 975 def run(self): 976 while self.count > 0: 977 item = self.queue.get() 978 print item 979 self.count = self.count - 1 980 981 NP = 3 982 QL = 4 983 NI = 5 984 985 Q = BoundedQueue(QL) 986 P = [] 987 for i in range(NP): 988 t = ProducerThread(Q, NI) 989 t.name = ("Producer-%d" % (i+1)) 990 P.append(t) 991 C = ConsumerThread(Q, NI*NP) 992 for t in P: 993 t.start() 994 _sleep(0.000001) 995 C.start() 996 for t in P: 997 t.join() 998 C.join() 999 1000if __name__ == '__main__': 1001 _test()