1 #
2 # Support for the API of the multiprocessing package using threads
3 #
4 # multiprocessing/dummy/__init__.py
5 #
6 # Copyright (c) 2006-2008, R Oudkerk
7 # Licensed to PSF under a Contributor Agreement.
8 #
9
10 __all__ = [
11 'Process', 'current_process', 'active_children', 'freeze_support',
12 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition',
13 'Event', 'Barrier', 'Queue', 'Manager', 'Pipe', 'Pool', 'JoinableQueue'
14 ]
15
16 #
17 # Imports
18 #
19
20 import threading
21 import sys
22 import weakref
23 import array
24
25 from .connection import Pipe
26 from threading import Lock, RLock, Semaphore, BoundedSemaphore
27 from threading import Event, Condition, Barrier
28 from queue import Queue
29
30 #
31 #
32 #
33
34 class ESC[4;38;5;81mDummyProcess(ESC[4;38;5;149mthreadingESC[4;38;5;149m.ESC[4;38;5;149mThread):
35
36 def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
37 threading.Thread.__init__(self, group, target, name, args, kwargs)
38 self._pid = None
39 self._children = weakref.WeakKeyDictionary()
40 self._start_called = False
41 self._parent = current_process()
42
43 def start(self):
44 if self._parent is not current_process():
45 raise RuntimeError(
46 "Parent is {0!r} but current_process is {1!r}".format(
47 self._parent, current_process()))
48 self._start_called = True
49 if hasattr(self._parent, '_children'):
50 self._parent._children[self] = None
51 threading.Thread.start(self)
52
53 @property
54 def exitcode(self):
55 if self._start_called and not self.is_alive():
56 return 0
57 else:
58 return None
59
60 #
61 #
62 #
63
64 Process = DummyProcess
65 current_process = threading.current_thread
66 current_process()._children = weakref.WeakKeyDictionary()
67
68 def active_children():
69 children = current_process()._children
70 for p in list(children):
71 if not p.is_alive():
72 children.pop(p, None)
73 return list(children)
74
75 def freeze_support():
76 pass
77
78 #
79 #
80 #
81
82 class ESC[4;38;5;81mNamespace(ESC[4;38;5;149mobject):
83 def __init__(self, /, **kwds):
84 self.__dict__.update(kwds)
85 def __repr__(self):
86 items = list(self.__dict__.items())
87 temp = []
88 for name, value in items:
89 if not name.startswith('_'):
90 temp.append('%s=%r' % (name, value))
91 temp.sort()
92 return '%s(%s)' % (self.__class__.__name__, ', '.join(temp))
93
94 dict = dict
95 list = list
96
97 def Array(typecode, sequence, lock=True):
98 return array.array(typecode, sequence)
99
100 class ESC[4;38;5;81mValue(ESC[4;38;5;149mobject):
101 def __init__(self, typecode, value, lock=True):
102 self._typecode = typecode
103 self._value = value
104
105 @property
106 def value(self):
107 return self._value
108
109 @value.setter
110 def value(self, value):
111 self._value = value
112
113 def __repr__(self):
114 return '<%s(%r, %r)>'%(type(self).__name__,self._typecode,self._value)
115
116 def Manager():
117 return sys.modules[__name__]
118
119 def shutdown():
120 pass
121
122 def Pool(processes=None, initializer=None, initargs=()):
123 from ..pool import ThreadPool
124 return ThreadPool(processes, initializer, initargs)
125
126 JoinableQueue = Queue