Frage

Ich schreibe ein Daemon-Programm mit Python 2.5. Im Hauptprozess wird ein Exit-Handler mit atexit Modul registriert, es scheint , dass der Handler, wenn jeder Prozess Kind aufgerufen wird beendet, was nicht ich erwartet hatte.

bemerkte ich dieses Verhalten nicht in Python atexit doc erwähnt, jemand kennt das Problem? Wenn dies ist, wie es sich verhalten soll, wie kann ich den Ausgang Handler bei Kindern Prozesse abzumelden? Es gibt eine atexit.unregister in der Version 3.0, aber ich bin mit 2.5.

War es hilfreich?

Lösung

Es gibt nicht eine API in Python 2.5 zu tun, aber man kann einfach:

import atexit
atexit._exithandlers = []

in Ihr Kind Prozesse - wenn Sie wissen, dass Sie nur einen Ausgang Handler installiert haben, und dass keine anderen Handler installiert sind. Beachten Sie jedoch, dass einige Teile des stdlib (z.B. logging) atexit Handler registrieren. Um zu vermeiden, auf sie trampeln, könnten Sie versuchen:

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)

wo my_handler_func ist die atexit Handler Sie registriert, und dies sollte Ihr Eintrag entfernen, ohne die anderen zu entfernen.

Andere Tipps

Wenn Sie ein Kind Prozess machen fork zu, ist das Kind eine exakte Kopie der Mutter - einschließlich natürlich registriert Exit-Funktionen sowie alle anderen Codes und Datenstrukturen. Ich glaube, das ist das Problem Sie beobachten -. Natürlich ist es nicht in jedem einzelnen Modul erwähnt, weil es notwendigerweise zu jedem einzelnen gilt

atexit.register() Register grundsätzlich Ihre Funktion in atexit._exithandlers, die ein Modul private Liste von Funktionen, die von sys.exitfunc() genannt wird. Sie können exitfunc() auf Ihre maßgeschneiderte Exit-Handler-Funktion eingestellt, die für die Kinder Status überprüft dann, oder einfach registriert er. Was ist nur das 3,0 atexit.py zu Ihrem lokalen Quellbaum zu kopieren und verwenden, dass statt?

EDIT: Ich habe die atexit.py von meiner Version 2.6 kopiert und erweitert es durch

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

Wenn Sie nehmen, dass anstelle der ursprünglichen Version sollte es funktionieren. Ich habe es nicht mit Subprozesse getestet, though.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top