changeset: 81931:0a58fa8e9bac branch: 2.7 user: Benjamin Peterson date: Sat Feb 02 11:15:50 2013 -0500 files: Lib/multiprocessing/util.py Misc/NEWS description: Issue #15881: Fixed atexit hook in multiprocessing. diff -r 8dffaa47bbf5 -r 0a58fa8e9bac Lib/multiprocessing/util.py --- a/Lib/multiprocessing/util.py Sat Feb 02 11:10:11 2013 -0500 +++ b/Lib/multiprocessing/util.py Sat Feb 02 11:15:50 2013 -0500 @@ -247,6 +247,12 @@ Finalizers with highest priority are called first; finalizers with the same priority will be called in reverse order of creation. ''' + if _finalizer_registry is None: + # This function may be called after this module's globals are + # destroyed. See the _exit_function function in this module for more + # notes. + return + if minpriority is None: f = lambda p : p[0][0] is not None else: @@ -278,21 +284,38 @@ _exiting = False -def _exit_function(): +def _exit_function(info=info, debug=debug, _run_finalizers=_run_finalizers, + active_children=active_children, + current_process=current_process): + # NB: we hold on to references to functions in the arglist due to the + # situation described below, where this function is called after this + # module's globals are destroyed. + global _exiting info('process shutting down') debug('running all "atexit" finalizers with priority>= 0') _run_finalizers(0) - for p in active_children(): - if p._daemonic: - info('calling terminate() for daemon %s', p.name) - p._popen.terminate() + if current_process() is not None: + # NB: we check if the current process is None here because if + # it's None, any call to ``active_children()`` will throw an + # AttributeError (active_children winds up trying to get + # attributes from util._current_process). This happens in a + # variety of shutdown circumstances that are not well-understood + # because module-scope variables are not apparently supposed to + # be destroyed until after this function is called. However, + # they are indeed destroyed before this function is called. See + # issues 9775 and 15881. Also related: 4106, 9205, and 9207. - for p in active_children(): - info('calling join() for process %s', p.name) - p.join() + for p in active_children(): + if p._daemonic: + info('calling terminate() for daemon %s', p.name) + p._popen.terminate() + + for p in active_children(): + info('calling join() for process %s', p.name) + p.join() debug('running the remaining "atexit" finalizers') _run_finalizers() diff -r 8dffaa47bbf5 -r 0a58fa8e9bac Misc/NEWS --- a/Misc/NEWS Sat Feb 02 11:10:11 2013 -0500 +++ b/Misc/NEWS Sat Feb 02 11:15:50 2013 -0500 @@ -202,6 +202,8 @@ Library ------- +- Issue #15881: Fixed atexit hook in multiprocessing. + - Issue #14340: Upgrade the embedded expat library to version 2.1.0. - Issue #11159: SAX parser now supports unicode file names.

AltStyle によって変換されたページ (->オリジナル) /