home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / Calibre / calibre-0.8.18.msi / file_262 / threading.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-09-09  |  22.6 KB  |  842 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.7)
  3.  
  4. import sys as _sys
  5.  
  6. try:
  7.     import thread
  8. except ImportError:
  9.     del _sys.modules[__name__]
  10.     raise 
  11.  
  12. import warnings
  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. __all__ = [
  17.     'activeCount',
  18.     'active_count',
  19.     'Condition',
  20.     'currentThread',
  21.     'current_thread',
  22.     'enumerate',
  23.     'Event',
  24.     'Lock',
  25.     'RLock',
  26.     'Semaphore',
  27.     'BoundedSemaphore',
  28.     'Thread',
  29.     'Timer',
  30.     'setprofile',
  31.     'settrace',
  32.     'local',
  33.     'stack_size']
  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. warnings.filterwarnings('ignore', category = DeprecationWarning, module = 'threading', message = 'sys.exc_clear')
  40. _VERBOSE = False
  41.  
  42. class _Verbose(object):
  43.     
  44.     def __init__(self, verbose = None):
  45.         pass
  46.  
  47.     
  48.     def _note(self, *args):
  49.         pass
  50.  
  51.  
  52. _profile_hook = None
  53. _trace_hook = None
  54.  
  55. def setprofile(func):
  56.     global _profile_hook
  57.     _profile_hook = func
  58.  
  59.  
  60. def settrace(func):
  61.     global _trace_hook
  62.     _trace_hook = func
  63.  
  64. Lock = _allocate_lock
  65.  
  66. def RLock(*args, **kwargs):
  67.     return _RLock(*args, **kwargs)
  68.  
  69.  
  70. class _RLock(_Verbose):
  71.     
  72.     def __init__(self, verbose = None):
  73.         _Verbose.__init__(self, verbose)
  74.         self._RLock__block = _allocate_lock()
  75.         self._RLock__owner = None
  76.         self._RLock__count = 0
  77.  
  78.     
  79.     def __repr__(self):
  80.         owner = self._RLock__owner
  81.         
  82.         try:
  83.             owner = _active[owner].name
  84.         except KeyError:
  85.             pass
  86.  
  87.         return '<%s owner=%r count=%d>' % (self.__class__.__name__, owner, self._RLock__count)
  88.  
  89.     
  90.     def acquire(self, blocking = 1):
  91.         me = _get_ident()
  92.         if self._RLock__owner == me:
  93.             self._RLock__count = self._RLock__count + 1
  94.             return 1
  95.         rc = None._RLock__block.acquire(blocking)
  96.         if rc:
  97.             self._RLock__owner = me
  98.             self._RLock__count = 1
  99.         return rc
  100.  
  101.     __enter__ = acquire
  102.     
  103.     def release(self):
  104.         if self._RLock__owner != _get_ident():
  105.             raise RuntimeError('cannot release un-acquired lock')
  106.         self._RLock__count = count = self._RLock__count - 1
  107.         if not count:
  108.             self._RLock__owner = None
  109.             self._RLock__block.release()
  110.  
  111.     
  112.     def __exit__(self, t, v, tb):
  113.         self.release()
  114.  
  115.     
  116.     def _acquire_restore(self, count_owner):
  117.         (count, owner) = count_owner
  118.         self._RLock__block.acquire()
  119.         self._RLock__count = count
  120.         self._RLock__owner = owner
  121.  
  122.     
  123.     def _release_save(self):
  124.         count = self._RLock__count
  125.         self._RLock__count = 0
  126.         owner = self._RLock__owner
  127.         self._RLock__owner = None
  128.         self._RLock__block.release()
  129.         return (count, owner)
  130.  
  131.     
  132.     def _is_owned(self):
  133.         return self._RLock__owner == _get_ident()
  134.  
  135.  
  136.  
  137. def Condition(*args, **kwargs):
  138.     return _Condition(*args, **kwargs)
  139.  
  140.  
  141. class _Condition(_Verbose):
  142.     
  143.     def __init__(self, lock = None, verbose = None):
  144.         _Verbose.__init__(self, verbose)
  145.         if lock is None:
  146.             lock = RLock()
  147.         self._Condition__lock = lock
  148.         self.acquire = lock.acquire
  149.         self.release = lock.release
  150.         
  151.         try:
  152.             self._release_save = lock._release_save
  153.         except AttributeError:
  154.             pass
  155.  
  156.         
  157.         try:
  158.             self._acquire_restore = lock._acquire_restore
  159.         except AttributeError:
  160.             pass
  161.  
  162.         
  163.         try:
  164.             self._is_owned = lock._is_owned
  165.         except AttributeError:
  166.             pass
  167.  
  168.         self._Condition__waiters = []
  169.  
  170.     
  171.     def __enter__(self):
  172.         return self._Condition__lock.__enter__()
  173.  
  174.     
  175.     def __exit__(self, *args):
  176.         return self._Condition__lock.__exit__(*args)
  177.  
  178.     
  179.     def __repr__(self):
  180.         return '<Condition(%s, %d)>' % (self._Condition__lock, len(self._Condition__waiters))
  181.  
  182.     
  183.     def _release_save(self):
  184.         self._Condition__lock.release()
  185.  
  186.     
  187.     def _acquire_restore(self, x):
  188.         self._Condition__lock.acquire()
  189.  
  190.     
  191.     def _is_owned(self):
  192.         if self._Condition__lock.acquire(0):
  193.             self._Condition__lock.release()
  194.             return False
  195.         return None
  196.  
  197.     
  198.     def wait(self, timeout = None):
  199.         if not self._is_owned():
  200.             raise RuntimeError('cannot wait on un-acquired lock')
  201.         waiter = _allocate_lock()
  202.         waiter.acquire()
  203.         self._Condition__waiters.append(waiter)
  204.         saved_state = self._release_save()
  205.         
  206.         try:
  207.             if timeout is None:
  208.                 waiter.acquire()
  209.             else:
  210.                 endtime = _time() + timeout
  211.                 delay = 0.0005
  212.                 while True:
  213.                     gotit = waiter.acquire(0)
  214.                     if gotit:
  215.                         break
  216.                     remaining = endtime - _time()
  217.                     if remaining <= 0:
  218.                         break
  219.                     delay = min(delay * 2, remaining, 0.05)
  220.                     _sleep(delay)
  221.                 if not gotit:
  222.                     
  223.                     try:
  224.                         self._Condition__waiters.remove(waiter)
  225.                     except ValueError:
  226.                         pass
  227.                     
  228.  
  229.                 self._acquire_restore(saved_state)
  230.                 return None
  231.  
  232.  
  233.     
  234.     def notify(self, n = 1):
  235.         if not self._is_owned():
  236.             raise RuntimeError('cannot notify on un-acquired lock')
  237.         _Condition__waiters = self._Condition__waiters
  238.         waiters = _Condition__waiters[:n]
  239.         if not waiters:
  240.             return None
  241.         if not n != 1 or 's':
  242.             pass
  243.         None._note('%s.notify(): notifying %d waiter%s', self, n, '')
  244.         for waiter in waiters:
  245.             waiter.release()
  246.             
  247.             try:
  248.                 _Condition__waiters.remove(waiter)
  249.             continue
  250.             except ValueError:
  251.                 continue
  252.             
  253.  
  254.         
  255.  
  256.     
  257.     def notifyAll(self):
  258.         self.notify(len(self._Condition__waiters))
  259.  
  260.     notify_all = notifyAll
  261.  
  262.  
  263. def Semaphore(*args, **kwargs):
  264.     return _Semaphore(*args, **kwargs)
  265.  
  266.  
  267. class _Semaphore(_Verbose):
  268.     
  269.     def __init__(self, value = 1, verbose = None):
  270.         if value < 0:
  271.             raise ValueError('semaphore initial value must be >= 0')
  272.         _Verbose.__init__(self, verbose)
  273.         self._Semaphore__cond = Condition(Lock())
  274.         self._Semaphore__value = value
  275.  
  276.     
  277.     def acquire(self, blocking = 1):
  278.         rc = False
  279.         self._Semaphore__cond.acquire()
  280.         while self._Semaphore__value == 0:
  281.             if not blocking:
  282.                 break
  283.             self._Semaphore__cond.wait()
  284.         self._Semaphore__value = self._Semaphore__value - 1
  285.         rc = True
  286.         self._Semaphore__cond.release()
  287.         return rc
  288.  
  289.     __enter__ = acquire
  290.     
  291.     def release(self):
  292.         self._Semaphore__cond.acquire()
  293.         self._Semaphore__value = self._Semaphore__value + 1
  294.         self._Semaphore__cond.notify()
  295.         self._Semaphore__cond.release()
  296.  
  297.     
  298.     def __exit__(self, t, v, tb):
  299.         self.release()
  300.  
  301.  
  302.  
  303. def BoundedSemaphore(*args, **kwargs):
  304.     return _BoundedSemaphore(*args, **kwargs)
  305.  
  306.  
  307. class _BoundedSemaphore(_Semaphore):
  308.     
  309.     def __init__(self, value = 1, verbose = None):
  310.         _Semaphore.__init__(self, value, verbose)
  311.         self._initial_value = value
  312.  
  313.     
  314.     def release(self):
  315.         if self._Semaphore__value >= self._initial_value:
  316.             raise ValueError, 'Semaphore released too many times'
  317.         return _Semaphore.release(self)
  318.  
  319.  
  320.  
  321. def Event(*args, **kwargs):
  322.     return _Event(*args, **kwargs)
  323.  
  324.  
  325. class _Event(_Verbose):
  326.     
  327.     def __init__(self, verbose = None):
  328.         _Verbose.__init__(self, verbose)
  329.         self._Event__cond = Condition(Lock())
  330.         self._Event__flag = False
  331.  
  332.     
  333.     def isSet(self):
  334.         return self._Event__flag
  335.  
  336.     is_set = isSet
  337.     
  338.     def set(self):
  339.         self._Event__cond.acquire()
  340.         
  341.         try:
  342.             self._Event__flag = True
  343.             self._Event__cond.notify_all()
  344.         finally:
  345.             self._Event__cond.release()
  346.  
  347.  
  348.     
  349.     def clear(self):
  350.         self._Event__cond.acquire()
  351.         
  352.         try:
  353.             self._Event__flag = False
  354.         finally:
  355.             self._Event__cond.release()
  356.  
  357.  
  358.     
  359.     def wait(self, timeout = None):
  360.         self._Event__cond.acquire()
  361.         
  362.         try:
  363.             if not self._Event__flag:
  364.                 self._Event__cond.wait(timeout)
  365.             return self._Event__flag
  366.         finally:
  367.             self._Event__cond.release()
  368.  
  369.  
  370.  
  371. _counter = 0
  372.  
  373. def _newname(template = 'Thread-%d'):
  374.     global _counter
  375.     _counter = _counter + 1
  376.     return template % _counter
  377.  
  378. _active_limbo_lock = _allocate_lock()
  379. _active = { }
  380. _limbo = { }
  381.  
  382. class Thread(_Verbose):
  383.     __initialized = False
  384.     __exc_info = _sys.exc_info
  385.     __exc_clear = _sys.exc_clear
  386.     
  387.     def __init__(self, group = None, target = None, name = None, args = (), kwargs = None, verbose = None):
  388.         _Verbose.__init__(self, verbose)
  389.         if kwargs is None:
  390.             kwargs = { }
  391.         self._Thread__target = target
  392.         if not name:
  393.             pass
  394.         self._Thread__name = str(_newname())
  395.         self._Thread__args = args
  396.         self._Thread__kwargs = kwargs
  397.         self._Thread__daemonic = self._set_daemon()
  398.         self._Thread__ident = None
  399.         self._Thread__started = Event()
  400.         self._Thread__stopped = False
  401.         self._Thread__block = Condition(Lock())
  402.         self._Thread__initialized = True
  403.         self._Thread__stderr = _sys.stderr
  404.  
  405.     
  406.     def _set_daemon(self):
  407.         return current_thread().daemon
  408.  
  409.     
  410.     def __repr__(self):
  411.         status = 'initial'
  412.         if self._Thread__started.is_set():
  413.             status = 'started'
  414.         if self._Thread__stopped:
  415.             status = 'stopped'
  416.         if self._Thread__daemonic:
  417.             status += ' daemon'
  418.         if self._Thread__ident is not None:
  419.             status += ' %s' % self._Thread__ident
  420.         return '<%s(%s, %s)>' % (self.__class__.__name__, self._Thread__name, status)
  421.  
  422.     
  423.     def start(self):
  424.         if not self._Thread__initialized:
  425.             raise RuntimeError('thread.__init__() not called')
  426.         if self._Thread__started.is_set():
  427.             raise RuntimeError('threads can only be started once')
  428.         with _active_limbo_lock:
  429.             _limbo[self] = self
  430.         
  431.         try:
  432.             _start_new_thread(self._Thread__bootstrap, ())
  433.         except Exception:
  434.             with _active_limbo_lock:
  435.                 del _limbo[self]
  436.         else:
  437.             raise 
  438.  
  439.         self._Thread__started.wait()
  440.  
  441.     
  442.     def run(self):
  443.         
  444.         try:
  445.             if self._Thread__target:
  446.                 self._Thread__target(*self._Thread__args, **self._Thread__kwargs)
  447.         finally:
  448.             del self._Thread__target
  449.             del self._Thread__args
  450.             del self._Thread__kwargs
  451.  
  452.  
  453.     
  454.     def __bootstrap(self):
  455.         
  456.         try:
  457.             self._Thread__bootstrap_inner()
  458.         except:
  459.             if self._Thread__daemonic and _sys is None:
  460.                 return None
  461.  
  462.  
  463.     
  464.     def _set_ident(self):
  465.         self._Thread__ident = _get_ident()
  466.  
  467.     
  468.     def __bootstrap_inner(self):
  469.         
  470.         try:
  471.             self._set_ident()
  472.             self._Thread__started.set()
  473.             with _active_limbo_lock:
  474.                 _active[self._Thread__ident] = self
  475.                 del _limbo[self]
  476.             if _trace_hook:
  477.                 self._note('%s.__bootstrap(): registering trace hook', self)
  478.                 _sys.settrace(_trace_hook)
  479.             if _profile_hook:
  480.                 self._note('%s.__bootstrap(): registering profile hook', self)
  481.                 _sys.setprofile(_profile_hook)
  482.             
  483.             try:
  484.                 self.run()
  485.             except SystemExit:
  486.                 pass
  487.             except:
  488.                 if _sys:
  489.                     _sys.stderr.write('Exception in thread %s:\n%s\n' % (self.name, _format_exc()))
  490.                 else:
  491.                     (exc_type, exc_value, exc_tb) = self._Thread__exc_info()
  492.                     
  493.                     try:
  494.                         print >>self._Thread__stderr, 'Exception in thread ' + self.name + ' (most likely raised during interpreter shutdown):'
  495.                         print >>self._Thread__stderr, 'Traceback (most recent call last):'
  496.                         while exc_tb:
  497.                             print >>self._Thread__stderr, '  File "%s", line %s, in %s' % (exc_tb.tb_frame.f_code.co_filename, exc_tb.tb_lineno, exc_tb.tb_frame.f_code.co_name)
  498.                             exc_tb = exc_tb.tb_next
  499.                         print >>self._Thread__stderr, '%s: %s' % (exc_type, exc_value)
  500.                     finally:
  501.                         del exc_type
  502.                         del exc_value
  503.                         del exc_tb
  504.  
  505.             finally:
  506.                 self._Thread__exc_clear()
  507.  
  508.         finally:
  509.             with _active_limbo_lock:
  510.                 self._Thread__stop()
  511.                 
  512.                 try:
  513.                     del _active[_get_ident()]
  514.                 except:
  515.                     pass
  516.  
  517.  
  518.  
  519.     
  520.     def __stop(self):
  521.         self._Thread__block.acquire()
  522.         self._Thread__stopped = True
  523.         self._Thread__block.notify_all()
  524.         self._Thread__block.release()
  525.  
  526.     
  527.     def __delete(self):
  528.         
  529.         try:
  530.             with _active_limbo_lock:
  531.                 del _active[_get_ident()]
  532.         except KeyError:
  533.             if 'dummy_threading' not in _sys.modules:
  534.                 raise 
  535.  
  536.  
  537.     
  538.     def join(self, timeout = None):
  539.         if not self._Thread__initialized:
  540.             raise RuntimeError('Thread.__init__() not called')
  541.         if not self._Thread__started.is_set():
  542.             raise RuntimeError('cannot join thread before it is started')
  543.         if self is current_thread():
  544.             raise RuntimeError('cannot join current thread')
  545.         self._Thread__block.acquire()
  546.         
  547.         try:
  548.             if timeout is None:
  549.                 while not self._Thread__stopped:
  550.                     self._Thread__block.wait()
  551.             else:
  552.                 deadline = _time() + timeout
  553.                 while not self._Thread__stopped:
  554.                     delay = deadline - _time()
  555.                     if delay <= 0:
  556.                         break
  557.                     self._Thread__block.wait(delay)
  558.         finally:
  559.             self._Thread__block.release()
  560.  
  561.  
  562.     
  563.     def name(self):
  564.         return self._Thread__name
  565.  
  566.     name = property(name)
  567.     
  568.     def name(self, name):
  569.         self._Thread__name = str(name)
  570.  
  571.     name = name.setter(name)
  572.     
  573.     def ident(self):
  574.         return self._Thread__ident
  575.  
  576.     ident = property(ident)
  577.     
  578.     def isAlive(self):
  579.         if self._Thread__started.is_set():
  580.             pass
  581.         return not (self._Thread__stopped)
  582.  
  583.     is_alive = isAlive
  584.     
  585.     def daemon(self):
  586.         return self._Thread__daemonic
  587.  
  588.     daemon = property(daemon)
  589.     
  590.     def daemon(self, daemonic):
  591.         if not self._Thread__initialized:
  592.             raise RuntimeError('Thread.__init__() not called')
  593.         if self._Thread__started.is_set():
  594.             raise RuntimeError('cannot set daemon status of active thread')
  595.         self._Thread__daemonic = daemonic
  596.  
  597.     daemon = daemon.setter(daemon)
  598.     
  599.     def isDaemon(self):
  600.         return self.daemon
  601.  
  602.     
  603.     def setDaemon(self, daemonic):
  604.         self.daemon = daemonic
  605.  
  606.     
  607.     def getName(self):
  608.         return self.name
  609.  
  610.     
  611.     def setName(self, name):
  612.         self.name = name
  613.  
  614.  
  615.  
  616. def Timer(*args, **kwargs):
  617.     return _Timer(*args, **kwargs)
  618.  
  619.  
  620. class _Timer(Thread):
  621.     
  622.     def __init__(self, interval, function, args = [], kwargs = { }):
  623.         Thread.__init__(self)
  624.         self.interval = interval
  625.         self.function = function
  626.         self.args = args
  627.         self.kwargs = kwargs
  628.         self.finished = Event()
  629.  
  630.     
  631.     def cancel(self):
  632.         self.finished.set()
  633.  
  634.     
  635.     def run(self):
  636.         self.finished.wait(self.interval)
  637.         if not self.finished.is_set():
  638.             self.function(*self.args, **self.kwargs)
  639.         self.finished.set()
  640.  
  641.  
  642.  
  643. class _MainThread(Thread):
  644.     
  645.     def __init__(self):
  646.         Thread.__init__(self, name = 'MainThread')
  647.         self._Thread__started.set()
  648.         self._set_ident()
  649.         with _active_limbo_lock:
  650.             _active[_get_ident()] = self
  651.  
  652.     
  653.     def _set_daemon(self):
  654.         return False
  655.  
  656.     
  657.     def _exitfunc(self):
  658.         self._Thread__stop()
  659.         t = _pickSomeNonDaemonThread()
  660.         if t:
  661.             pass
  662.         while t:
  663.             t.join()
  664.             t = _pickSomeNonDaemonThread()
  665.         self._Thread__delete()
  666.  
  667.  
  668.  
  669. def _pickSomeNonDaemonThread():
  670.     for t in enumerate():
  671.         if not (t.daemon) and t.is_alive():
  672.             return t
  673.     
  674.  
  675.  
  676. class _DummyThread(Thread):
  677.     
  678.     def __init__(self):
  679.         Thread.__init__(self, name = _newname('Dummy-%d'))
  680.         del self._Thread__block
  681.         self._Thread__started.set()
  682.         self._set_ident()
  683.         with _active_limbo_lock:
  684.             _active[_get_ident()] = self
  685.  
  686.     
  687.     def _set_daemon(self):
  688.         return True
  689.  
  690.     
  691.     def join(self, timeout = None):
  692.         pass
  693.  
  694.  
  695.  
  696. def currentThread():
  697.     
  698.     try:
  699.         return _active[_get_ident()]
  700.     except KeyError:
  701.         return _DummyThread()
  702.  
  703.  
  704. current_thread = currentThread
  705.  
  706. def activeCount():
  707.     with _active_limbo_lock:
  708.         return len(_active) + len(_limbo)
  709.  
  710. active_count = activeCount
  711.  
  712. def _enumerate():
  713.     return _active.values() + _limbo.values()
  714.  
  715.  
  716. def enumerate():
  717.     with _active_limbo_lock:
  718.         return _active.values() + _limbo.values()
  719.  
  720. from thread import stack_size
  721. _shutdown = _MainThread()._exitfunc
  722.  
  723. try:
  724.     from thread import _local as local
  725. except ImportError:
  726.     from _threading_local import local
  727.  
  728.  
  729. def _after_fork():
  730.     global _active_limbo_lock
  731.     _active_limbo_lock = _allocate_lock()
  732.     new_active = { }
  733.     current = current_thread()
  734.     with _active_limbo_lock:
  735.         for thread in _active.itervalues():
  736.             if thread is current:
  737.                 ident = _get_ident()
  738.                 thread._Thread__ident = ident
  739.                 new_active[ident] = thread
  740.                 continue
  741.             thread._Thread__stopped = True
  742.         
  743.         _limbo.clear()
  744.         _active.clear()
  745.         _active.update(new_active)
  746.  
  747.  
  748. def _test():
  749.     
  750.     class BoundedQueue(_Verbose):
  751.         
  752.         def __init__(self, limit):
  753.             _Verbose.__init__(self)
  754.             self.mon = RLock()
  755.             self.rc = Condition(self.mon)
  756.             self.wc = Condition(self.mon)
  757.             self.limit = limit
  758.             self.queue = deque()
  759.  
  760.         
  761.         def put(self, item):
  762.             self.mon.acquire()
  763.             while len(self.queue) >= self.limit:
  764.                 self._note('put(%s): queue full', item)
  765.                 self.wc.wait()
  766.             self.queue.append(item)
  767.             self._note('put(%s): appended, length now %d', item, len(self.queue))
  768.             self.rc.notify()
  769.             self.mon.release()
  770.  
  771.         
  772.         def get(self):
  773.             self.mon.acquire()
  774.             while not self.queue:
  775.                 self._note('get(): queue empty')
  776.                 self.rc.wait()
  777.             item = self.queue.popleft()
  778.             self._note('get(): got %s, %d left', item, len(self.queue))
  779.             self.wc.notify()
  780.             self.mon.release()
  781.             return item
  782.  
  783.  
  784.     
  785.     class ProducerThread(Thread):
  786.         
  787.         def __init__(self, queue, quota):
  788.             Thread.__init__(self, name = 'Producer')
  789.             self.queue = queue
  790.             self.quota = quota
  791.  
  792.         
  793.         def run(self):
  794.             random = random
  795.             import random
  796.             counter = 0
  797.             while counter < self.quota:
  798.                 counter = counter + 1
  799.                 self.queue.put('%s.%d' % (self.name, counter))
  800.                 _sleep(random() * 1e-05)
  801.  
  802.  
  803.     
  804.     class ConsumerThread(Thread):
  805.         
  806.         def __init__(self, queue, count):
  807.             Thread.__init__(self, name = 'Consumer')
  808.             self.queue = queue
  809.             self.count = count
  810.  
  811.         
  812.         def run(self):
  813.             while self.count > 0:
  814.                 item = self.queue.get()
  815.                 print item
  816.                 self.count = self.count - 1
  817.  
  818.  
  819.     NP = 3
  820.     QL = 4
  821.     NI = 5
  822.     Q = BoundedQueue(QL)
  823.     P = []
  824.     for i in range(NP):
  825.         t = ProducerThread(Q, NI)
  826.         t.name = 'Producer-%d' % (i + 1)
  827.         P.append(t)
  828.     
  829.     C = ConsumerThread(Q, NI * NP)
  830.     for t in P:
  831.         t.start()
  832.         _sleep(1e-06)
  833.     
  834.     C.start()
  835.     for t in P:
  836.         t.join()
  837.     
  838.     C.join()
  839.  
  840. if __name__ == '__main__':
  841.     _test()
  842.