12

我有一些子进程(使用多处理),当它们停止时,它们每个都需要做一些最后的工作。像下面这样的东西,虽然没有用......

import multiprocessing
import atexit

def final():
    print "final work"

def worker():
    print 'Doing some work'
    atexit.register(final)

if __name__ == '__main__':
    p = multiprocessing.Process(target=worker)
    p.start()
    p.join()

那么我该怎么做呢?

4

2 回答 2

9

通过多处理启动的进程不会正常退出,并且atexit永远不会调用函数。您必须通过 try/finally 块手动运行清理工作,例如:

def worker():
    try:
        print('Doing some work')
    finally:
        final()

或者,如果您真的想使用atexit(请参阅下面的缺点):

def worker():
    try:
        print('Doing some work')
    finally:
        atexit._run_exitfuncs()

为什么子进程不能正常退出?

从技术上讲,因为他们通过 退出os._exit(),跳过任何清理工作(包括atexit函数__del__()和弱引用终结器)。

这个决定背后的原因是清理工作有在错误的时间、错误的过程中执行的风险。大多数使用atexit(或其他机制)的代码都希望代码只执行一次,并且仅在主解释器退出时(例如,可以atexit用来删除临时目录)。通过在每次子进程退出时执行atexit函数,您打破了这种期望,并且可能会发生坏事。

因此,即使您可以atexit通过 运行函数,也请atexit._run_exitfuncs()避免这样做,因为该函数未记录在案,并且您可能不是唯一的用户atexit(其他第三方库可能会使用它,并且您可能会在他们的代码中引入错误)。

于 2015-12-29T08:47:05.523 回答
0

您可以使用这种atexit支持多进程的替换。

它只会调用进程本身注册的函数,而不是任何其他继承我的父进程或任何东西。

https://github.com/kuralabs/multiexit

于 2018-04-07T05:35:34.630 回答