如何注册" atexit"函数在python的多处理子进程中?

时间:2015-12-29 07:39:41

标签: python multiprocess atexit

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

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()

那我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

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

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

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

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

为什么子进程没有正常退出?

从技术上讲,因为they quit via os._exit(),跳过任何清理工作(包括atexit函数,__del__()和weakref终结器)。

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

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

答案 1 :(得分:0)

您可以使用可识别多进程的atexit替换。

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

https://github.com/kuralabs/multiexit