Question

I am writing a daemon program using python 2.5. In the main process an exit handler is registered with atexit module, it seems that the handler gets called when each child process ends, which is not I expected.

I noticed this behavior isn't mentioned in python atexit doc, anybody knows the issue? If this is how it should behave, how can I unregister the exit handler in children processes? There is a atexit.unregister in version 3.0, but I am using 2.5.

Was it helpful?

Solution

There isn't an API to do it in Python 2.5, but you can just:

import atexit
atexit._exithandlers = []

in your child processes - if you know you only have one exit handler installed, and that no other handlers are installed. However, be aware that some parts of the stdlib (e.g. logging) register atexit handlers. To avoid trampling on them, you could try:

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)

where my_handler_func is the atexit handler you registered, and this should remove your entry without removing the others.

OTHER TIPS

When you fork to make a child process, that child is an exact copy of the parent -- including of course registered exit functions as well as all other code and data structures. I believe that's the issue you're observing -- of course it's not mentioned in each and every module, because it necessarily applies to every single one.

atexit.register() basically registers your function in atexit._exithandlers, which is a module private list of functions called by sys.exitfunc(). You can set exitfunc() to your custom made exit handler function, which then checks for child status or simply unregisters it. What about just copying the 3.0 atexit.py to your local source tree and using that instead?

EDIT: I copied the atexit.py from my 2.6 version and extended it by

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

If you take that instead of your original version it should work. I have not tested it with subprocesses, though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top