|
1 # |
|
2 # Package analogous to 'threading.py' but using processes |
|
3 # |
|
4 # multiprocessing/__init__.py |
|
5 # |
|
6 # This package is intended to duplicate the functionality (and much of |
|
7 # the API) of threading.py but uses processes instead of threads. A |
|
8 # subpackage 'multiprocessing.dummy' has the same API but is a simple |
|
9 # wrapper for 'threading'. |
|
10 # |
|
11 # Try calling `multiprocessing.doc.main()` to read the html |
|
12 # documentation in in a webbrowser. |
|
13 # |
|
14 # |
|
15 # Copyright (c) 2006-2008, R Oudkerk |
|
16 # All rights reserved. |
|
17 # |
|
18 # Redistribution and use in source and binary forms, with or without |
|
19 # modification, are permitted provided that the following conditions |
|
20 # are met: |
|
21 # |
|
22 # 1. Redistributions of source code must retain the above copyright |
|
23 # notice, this list of conditions and the following disclaimer. |
|
24 # 2. Redistributions in binary form must reproduce the above copyright |
|
25 # notice, this list of conditions and the following disclaimer in the |
|
26 # documentation and/or other materials provided with the distribution. |
|
27 # 3. Neither the name of author nor the names of any contributors may be |
|
28 # used to endorse or promote products derived from this software |
|
29 # without specific prior written permission. |
|
30 # |
|
31 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND |
|
32 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
33 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
34 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
|
35 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
36 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
37 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
38 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
39 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
40 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
41 # |
|
42 |
|
43 __version__ = '0.70a1' |
|
44 |
|
45 __all__ = [ |
|
46 'Process', 'current_process', 'active_children', 'freeze_support', |
|
47 'Manager', 'Pipe', 'cpu_count', 'log_to_stderr', 'get_logger', |
|
48 'allow_connection_pickling', 'BufferTooShort', 'TimeoutError', |
|
49 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', |
|
50 'Event', 'Queue', 'JoinableQueue', 'Pool', 'Value', 'Array', |
|
51 'RawValue', 'RawArray' |
|
52 ] |
|
53 |
|
54 __author__ = 'R. Oudkerk (r.m.oudkerk@gmail.com)' |
|
55 |
|
56 # |
|
57 # Imports |
|
58 # |
|
59 |
|
60 import os |
|
61 import sys |
|
62 |
|
63 from multiprocessing.process import Process, current_process, active_children |
|
64 |
|
65 # |
|
66 # Exceptions |
|
67 # |
|
68 |
|
69 class ProcessError(Exception): |
|
70 pass |
|
71 |
|
72 class BufferTooShort(ProcessError): |
|
73 pass |
|
74 |
|
75 class TimeoutError(ProcessError): |
|
76 pass |
|
77 |
|
78 class AuthenticationError(ProcessError): |
|
79 pass |
|
80 |
|
81 # This is down here because _multiprocessing uses BufferTooShort |
|
82 import _multiprocessing |
|
83 |
|
84 # |
|
85 # Definitions not depending on native semaphores |
|
86 # |
|
87 |
|
88 def Manager(): |
|
89 ''' |
|
90 Returns a manager associated with a running server process |
|
91 |
|
92 The managers methods such as `Lock()`, `Condition()` and `Queue()` |
|
93 can be used to create shared objects. |
|
94 ''' |
|
95 from multiprocessing.managers import SyncManager |
|
96 m = SyncManager() |
|
97 m.start() |
|
98 return m |
|
99 |
|
100 def Pipe(duplex=True): |
|
101 ''' |
|
102 Returns two connection object connected by a pipe |
|
103 ''' |
|
104 from multiprocessing.connection import Pipe |
|
105 return Pipe(duplex) |
|
106 |
|
107 def cpu_count(): |
|
108 ''' |
|
109 Returns the number of CPUs in the system |
|
110 ''' |
|
111 if sys.platform == 'win32': |
|
112 try: |
|
113 num = int(os.environ['NUMBER_OF_PROCESSORS']) |
|
114 except (ValueError, KeyError): |
|
115 num = 0 |
|
116 elif sys.platform == 'darwin': |
|
117 try: |
|
118 num = int(os.popen('sysctl -n hw.ncpu').read()) |
|
119 except ValueError: |
|
120 num = 0 |
|
121 else: |
|
122 try: |
|
123 num = os.sysconf('SC_NPROCESSORS_ONLN') |
|
124 except (ValueError, OSError, AttributeError): |
|
125 num = 0 |
|
126 |
|
127 if num >= 1: |
|
128 return num |
|
129 else: |
|
130 raise NotImplementedError('cannot determine number of cpus') |
|
131 |
|
132 def freeze_support(): |
|
133 ''' |
|
134 Check whether this is a fake forked process in a frozen executable. |
|
135 If so then run code specified by commandline and exit. |
|
136 ''' |
|
137 if sys.platform == 'win32' and getattr(sys, 'frozen', False): |
|
138 from multiprocessing.forking import freeze_support |
|
139 freeze_support() |
|
140 |
|
141 def get_logger(): |
|
142 ''' |
|
143 Return package logger -- if it does not already exist then it is created |
|
144 ''' |
|
145 from multiprocessing.util import get_logger |
|
146 return get_logger() |
|
147 |
|
148 def log_to_stderr(level=None): |
|
149 ''' |
|
150 Turn on logging and add a handler which prints to stderr |
|
151 ''' |
|
152 from multiprocessing.util import log_to_stderr |
|
153 return log_to_stderr(level) |
|
154 |
|
155 def allow_connection_pickling(): |
|
156 ''' |
|
157 Install support for sending connections and sockets between processes |
|
158 ''' |
|
159 from multiprocessing import reduction |
|
160 |
|
161 # |
|
162 # Definitions depending on native semaphores |
|
163 # |
|
164 |
|
165 def Lock(): |
|
166 ''' |
|
167 Returns a non-recursive lock object |
|
168 ''' |
|
169 from multiprocessing.synchronize import Lock |
|
170 return Lock() |
|
171 |
|
172 def RLock(): |
|
173 ''' |
|
174 Returns a recursive lock object |
|
175 ''' |
|
176 from multiprocessing.synchronize import RLock |
|
177 return RLock() |
|
178 |
|
179 def Condition(lock=None): |
|
180 ''' |
|
181 Returns a condition object |
|
182 ''' |
|
183 from multiprocessing.synchronize import Condition |
|
184 return Condition(lock) |
|
185 |
|
186 def Semaphore(value=1): |
|
187 ''' |
|
188 Returns a semaphore object |
|
189 ''' |
|
190 from multiprocessing.synchronize import Semaphore |
|
191 return Semaphore(value) |
|
192 |
|
193 def BoundedSemaphore(value=1): |
|
194 ''' |
|
195 Returns a bounded semaphore object |
|
196 ''' |
|
197 from multiprocessing.synchronize import BoundedSemaphore |
|
198 return BoundedSemaphore(value) |
|
199 |
|
200 def Event(): |
|
201 ''' |
|
202 Returns an event object |
|
203 ''' |
|
204 from multiprocessing.synchronize import Event |
|
205 return Event() |
|
206 |
|
207 def Queue(maxsize=0): |
|
208 ''' |
|
209 Returns a queue object |
|
210 ''' |
|
211 from multiprocessing.queues import Queue |
|
212 return Queue(maxsize) |
|
213 |
|
214 def JoinableQueue(maxsize=0): |
|
215 ''' |
|
216 Returns a queue object |
|
217 ''' |
|
218 from multiprocessing.queues import JoinableQueue |
|
219 return JoinableQueue(maxsize) |
|
220 |
|
221 def Pool(processes=None, initializer=None, initargs=()): |
|
222 ''' |
|
223 Returns a process pool object |
|
224 ''' |
|
225 from multiprocessing.pool import Pool |
|
226 return Pool(processes, initializer, initargs) |
|
227 |
|
228 def RawValue(typecode_or_type, *args): |
|
229 ''' |
|
230 Returns a shared object |
|
231 ''' |
|
232 from multiprocessing.sharedctypes import RawValue |
|
233 return RawValue(typecode_or_type, *args) |
|
234 |
|
235 def RawArray(typecode_or_type, size_or_initializer): |
|
236 ''' |
|
237 Returns a shared array |
|
238 ''' |
|
239 from multiprocessing.sharedctypes import RawArray |
|
240 return RawArray(typecode_or_type, size_or_initializer) |
|
241 |
|
242 def Value(typecode_or_type, *args, **kwds): |
|
243 ''' |
|
244 Returns a synchronized shared object |
|
245 ''' |
|
246 from multiprocessing.sharedctypes import Value |
|
247 return Value(typecode_or_type, *args, **kwds) |
|
248 |
|
249 def Array(typecode_or_type, size_or_initializer, **kwds): |
|
250 ''' |
|
251 Returns a synchronized shared array |
|
252 ''' |
|
253 from multiprocessing.sharedctypes import Array |
|
254 return Array(typecode_or_type, size_or_initializer, **kwds) |
|
255 |
|
256 # |
|
257 # |
|
258 # |
|
259 |
|
260 if sys.platform == 'win32': |
|
261 |
|
262 def set_executable(executable): |
|
263 ''' |
|
264 Sets the path to a python.exe or pythonw.exe binary used to run |
|
265 child processes on Windows instead of sys.executable. |
|
266 Useful for people embedding Python. |
|
267 ''' |
|
268 from multiprocessing.forking import set_executable |
|
269 set_executable(executable) |
|
270 |
|
271 __all__ += ['set_executable'] |