2009-06-27 24 views
2

我写使用Python 2.5的服务程序。在主进程退出处理程序与atexit模块注册,它似乎,当每个子进程结束的处理程序被调用,这是不是我的预期。由生成的子进程继承的已注册的atexit处理程序?

我注意到这种行为是不是在蟒蛇atexit文档提到,任何人知道这个问题?如果这是它的行为方式,我怎样才能注销子进程中的退出处理程序? 3.0版中有一个atexit.unregister,但我使用的是2.5。

回答

3

没有一个API来做到这一点在Python 2.5,但你可以:

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处理程序,这应该删除您的项目而不删除他人。

1

atexit.register()基本上将您的功能注册到atexit._exithandlers,这是sys.exitfunc()所称的功能模块专用列表。您可以设置exitfunc()您定制的退出处理函数,然后检查孩子的状态或者干脆注销了。那么把3.0 atexit.py复制到本地源代码树并使用它代替它呢?

编辑:我从我的2.6版复制atexit.py和

def unregister(func, *targs, **kargs): 
    _exithandlers.remove((func, targs, kargs)) 

扩展它,如果你采取的,而不是你原来的版本它应该工作。不过,我还没有用子流程对它进行测试。

+0

3.0中没有atext.py,3.0中的atexit模块是用C编写的。 – btw0 2009-06-27 14:28:20

+0

没错,但是你也可以从2.x版本中取出atexit.py – 2009-06-30 09:52:29

3

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

+0

当然,我倾向于在实践中忘记基本的CS事实,谢谢你提醒这一点。 – btw0 2009-06-30 13:37:18