注册的atexit处理程序是由生成的子进程继承的吗?

时间:2009-06-27 11:54:08

标签: python multiprocessing atexit

我正在使用python 2.5编写一个守护程序。在主进程中,退出处理程序在atexit模块中注册,似乎在每个子进程结束时调用处理程序,这不是我预期的。

我注意到python atexit doc中没有提到这种行为,有谁知道这个问题?如果这是它应该如何表现,我如何取消注册子进程中的退出处理程序?版本3.0中有一个atexit.unregister,但我使用的是2.5。

3 个答案:

答案 0 :(得分:3)

当您fork进行子进程时,该子进程是父进程的精确副本 - 当然包括已注册的退出函数以及所有其他代码和数据结构。我相信这是你正在观察的问题 - 当然,每个模块都没有提到它,因为它必然适用于每一个模块。

答案 1 :(得分:3)

在Python 2.5中没有API可以执行此操作,但您可以:

import atexit
atexit._exithandlers = []
您的子进程中的

- 如果您知道只安装了一个出口处理程序,并且没有安装其他处理程序。但是,请注意stdlib的某些部分(例如logging)注册atexit个处理程序。为了避免践踏它们,您可以尝试:

my_handler_entries = [e for e in atexit._exithandlers if e[0] == my_handler_func]
for e in my_handler_entries:
    atexit._exithandlers.remove(e)

其中my_handler_func是您注册的atexit处理程序,这应删除您的条目而不删除其他条目。

答案 2 :(得分:1)

atexit.register()基本上在atexit._exithandlers中注册您的函数,sys.exitfunc()是由exitfunc()调用的模块私有函数列表。您可以将atexit.py设置为自定义的退出处理函数,然后检查子状态或只是取消注册它。如何将3.0 def unregister(func, *targs, **kargs): _exithandlers.remove((func, targs, kargs)) 复制到本地源代码树并使用它呢?

编辑:我从我的2.6版本复制了atexit.py并通过

进行了扩展
{{1}}

如果您使用它而不是原始版本它应该工作。不过,我还没有用子进程测试它。