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:

  • Python 2.6.x theading / signal / atexit scheitern bei einigen Versionen?
  • Python Multiprocessing atexit Fehler "Fehler in atexit._run_exitfuncs"
  • Wie finde ich Exit-Code oder Grund, wenn atexit Callback in Python aufgerufen wird?
  • Der Aufruf von Signalhandler und Atexit-Handler in Python
  • Fehler beim Multiprocessing, Atexit und globalen Daten
  •  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 3.0.1 Executable Creator
  • Wie man die Größe von exe mit py2exe zu reduzieren
  • Python - erstellen Sie eine EXE, die Code wie geschrieben, nicht wie es war, wenn kompiliert
  • Python 3.2.2, Fehler (Skripte zu exe)
  • Mehrere Skripts in PyInstaller verpacken
  • PyInstaller Problem
  • 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.