Python-Prozess wird nicht atexit aufrufen

Ich versuche, atexit in einem Process , aber leider scheint es nicht zu arbeiten. Hier ist ein Beispielcode:

 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:

  • Der Aufruf von Signalhandler und Atexit-Handler in Python
  • Python 2.6.x theading / signal / atexit scheitern bei einigen Versionen?
  • Fehler beim Multiprocessing, Atexit und globalen Daten
  • Python Multiprocessing atexit Fehler "Fehler in atexit._run_exitfuncs"
  • Wie finde ich Exit-Code oder Grund, wenn atexit Callback in Python aufgerufen wird?
  •  DEBUG: root: Hauptprozess wurde gestartet
     DEBUG: root: W-1 gestartet
     DEBUG: Wurzel: W-2 gestartet
     DEBUG: root: Hauptprozess beendet
    

    Ich würde erwarten, dass die W.run.log_terminate() aufgerufen werden würde, wenn a.terminate() und b.terminate() aufgerufen werden, und die Ausgabe ist etwas wie Likeso (Hervorhebung hinzugefügt) !:

     DEBUG: root: Hauptprozess wurde gestartet
     DEBUG: root: W-1 gestartet
     DEBUG: Wurzel: W-2 gestartet
     DEBUG: Wurzel: W-1 beendet! 
      DEBUG: Wurzel: W-2 beendet!
     DEBUG: root: Hauptprozess beendet
    

    Warum funktioniert das nicht, und gibt es einen besseren Weg, um eine Nachricht (aus dem Process Kontext) zu protokollieren, wenn ein Process beendet wird?

    Vielen Dank für Ihre Eingabe – es wird sehr geschätzt.

    Lösung

    EDIT: Basierend auf der von Alex Martelli vorgeschlagenen Lösung, wie folgt:

     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 fehlerhafter Fehler des Python erkannt wird oder wenn os._exit () aufgerufen wird.

  • Python - erstellen Sie eine EXE, die Code wie geschrieben, nicht wie es war, wenn kompiliert
  • Python 3.2.2, Fehler (Skripte zu exe)
  • Python: Kann ich ein Python-Skript laufen lassen, ohne tatsächlich Python zu installieren?
  • Wie kann die Terminal-Ausgabe von ausführbaren Dateien, die von Python-Funktionen ausgeführt werden, ganz allgemein ausgeschaltet werden?
  • Packe eine Software in Python mit py2exe mit 'libiomp5md.dll' nicht gefunden
  • Python 3.0.1 Executable Creator
  • One Solution collect form web for “Python-Prozess wird nicht atexit aufrufen”

    Wie die docs sagen,

    Bei Unix erfolgt dies mit dem SIGTERM-Signal; Unter Windows TerminateProcess () wird verwendet. Beachten Sie, dass Exit-Handler und endgültige Klauseln usw. nicht ausgeführt werden.

    Wenn du auf Unix bist, solltest du SIGTERM mit Signal abfangen und irgendwelche "Kündigungsaktivitäten" ausführen, die du brauchst Allerdings weiß ich nicht von einer plattformübergreifenden Lösung.

    Python ist die beste Programmiersprache der Welt.