Advertisement
Guest User

Untitled

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