Python-Prozess wird nicht atexit nennen
-
23-09-2019 - |
Frage
Ich versuche atexit
in einem Process
zu verwenden, aber leider scheint es nicht zu arbeiten. Hier einige Beispiel-Code:
import time
import atexit
import logging
import multiprocessing
logging.basicConfig(level=logging.DEBUG)
class W(multiprocessing.Process):
def run(self):
logging.debug("%s Started" % self.name)
@atexit.register
def log_terminate():
# ever called?
logging.debug("%s Terminated!" % self.name)
while True:
time.sleep(10)
@atexit.register
def log_exit():
logging.debug("Main process terminated")
logging.debug("Main process started")
a = W()
b = W()
a.start()
b.start()
time.sleep(1)
a.terminate()
b.terminate()
Die Ausgabe dieses Codes ist:
DEBUG:root:Main process started DEBUG:root:W-1 Started DEBUG:root:W-2 Started DEBUG:root:Main process terminated
Ich würde erwarten, dass die W.run.log_terminate()
genannt werden würden, wenn a.terminate()
und b.terminate()
genannt werden, und die Ausgabe etwas sein likeso (Hervorhebung hinzugefügt):
DEBUG:root:Main process started DEBUG:root:W-1 Started DEBUG:root:W-2 Started DEBUG:root:W-1 Terminated! DEBUG:root:W-2 Terminated! DEBUG:root:Main process terminated
Warum ist das nicht funktioniert, und gibt es eine bessere Art und Weise eine Nachricht zu protokollieren (aus dem Process
Kontext), wenn ein Process
beendet wird?
Vielen Dank für Ihre Eingabe - es ist sehr zu schätzen
.Lösung
EDIT: Basierend auf Lösung von Alex Martelli vorgeschlagen, wie die folgenden Werke zu erwarten:
import sys
import time
import atexit
import signal
import logging
import multiprocessing
logging.basicConfig(level=logging.DEBUG)
class W(multiprocessing.Process):
def run(self):
logging.debug("%s Started" % self.name)
def log_terminate(num, frame):
logging.debug("%s Terminated" % self.name)
sys.exit()
signal.signal(signal.SIGTERM, log_terminate)
while True:
time.sleep(10)
@atexit.register
def log_exit():
logging.debug("Main process terminated")
logging.debug("Main process started")
a = W()
b = W()
a.start()
b.start()
time.sleep(1)
a.terminate()
b.terminate()
Es lohnt sich, den folgenden Kommentar in der atexit
Dokumentation zu beachten:
. Hinweis: die über dieses Modul registrierten Funktionen werden nicht aufgerufen, wenn das Programm durch ein Signal getötet wird, wenn ein Python schwerwiegende internen Fehler erkannt werden, oder wenn os._exit () aufgerufen wird
Lösung
Wie die docs sagen,
Auf Unix dies geschieht, um die SIGTERM mit Signal; unter Windows TerminateProcess () wird genutzt. Beachten Sie, dass Exit-Handler und schließlich Klauseln etc., werden nicht ausgeführt wird.
Wenn Sie auf Unix sind, sollten Sie in der Lage abfangen SIGTERM
sein mit