Changeset 391 for python/trunk/Lib/multiprocessing/util.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/multiprocessing/util.py
r2 r391 4 4 # multiprocessing/util.py 5 5 # 6 # Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt 6 # Copyright (c) 2006-2008, R Oudkerk 7 # All rights reserved. 8 # 9 # Redistribution and use in source and binary forms, with or without 10 # modification, are permitted provided that the following conditions 11 # are met: 12 # 13 # 1. Redistributions of source code must retain the above copyright 14 # notice, this list of conditions and the following disclaimer. 15 # 2. Redistributions in binary form must reproduce the above copyright 16 # notice, this list of conditions and the following disclaimer in the 17 # documentation and/or other materials provided with the distribution. 18 # 3. Neither the name of author nor the names of any contributors may be 19 # used to endorse or promote products derived from this software 20 # without specific prior written permission. 21 # 22 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND 23 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 # SUCH DAMAGE. 7 33 # 8 34 … … 12 38 import threading # we want threading to install it's 13 39 # cleanup function before multiprocessing does 40 from subprocess import _args_from_interpreter_flags 14 41 15 42 from multiprocessing.process import current_process, active_children … … 222 249 the same priority will be called in reverse order of creation. 223 250 ''' 251 if _finalizer_registry is None: 252 # This function may be called after this module's globals are 253 # destroyed. See the _exit_function function in this module for more 254 # notes. 255 return 256 224 257 if minpriority is None: 225 258 f = lambda p : p[0][0] is not None … … 253 286 _exiting = False 254 287 255 def _exit_function(): 288 def _exit_function(info=info, debug=debug, _run_finalizers=_run_finalizers, 289 active_children=active_children, 290 current_process=current_process): 291 # NB: we hold on to references to functions in the arglist due to the 292 # situation described below, where this function is called after this 293 # module's globals are destroyed. 294 256 295 global _exiting 257 296 … … 260 299 _run_finalizers(0) 261 300 262 for p in active_children(): 263 if p._daemonic: 264 info('calling terminate() for daemon %s', p.name) 265 p._popen.terminate() 266 267 for p in active_children(): 268 info('calling join() for process %s', p.name) 269 p.join() 301 if current_process() is not None: 302 # NB: we check if the current process is None here because if 303 # it's None, any call to ``active_children()`` will throw an 304 # AttributeError (active_children winds up trying to get 305 # attributes from util._current_process). This happens in a 306 # variety of shutdown circumstances that are not well-understood 307 # because module-scope variables are not apparently supposed to 308 # be destroyed until after this function is called. However, 309 # they are indeed destroyed before this function is called. See 310 # issues 9775 and 15881. Also related: 4106, 9205, and 9207. 311 312 for p in active_children(): 313 if p._daemonic: 314 info('calling terminate() for daemon %s', p.name) 315 p._popen.terminate() 316 317 for p in active_children(): 318 info('calling join() for process %s', p.name) 319 p.join() 270 320 271 321 debug('running the remaining "atexit" finalizers') … … 280 330 class ForkAwareThreadLock(object): 281 331 def __init__(self): 332 self._reset() 333 register_after_fork(self, ForkAwareThreadLock._reset) 334 335 def _reset(self): 282 336 self._lock = threading.Lock() 283 337 self.acquire = self._lock.acquire 284 338 self.release = self._lock.release 285 register_after_fork(self, ForkAwareThreadLock.__init__)286 339 287 340 class ForkAwareLocal(threading.local):
Note:
See TracChangeset
for help on using the changeset viewer.