我正在使用python 2.5编写一个守护程序。在主进程中,退出处理程序在atexit
模块中注册,似乎在每个子进程结束时调用处理程序,这不是我预期的。
我注意到python atexit
doc中没有提到这种行为,有谁知道这个问题?如果这是它应该如何表现,我如何取消注册子进程中的退出处理程序?版本3.0中有一个atexit.unregister,但我使用的是2.5。
答案 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}}
如果您使用它而不是原始版本它应该工作。不过,我还没有用子进程测试它。