Processus Python ne sera pas appeler atexit
-
23-09-2019 - |
Question
Je suis en train d'utiliser atexit
dans un Process
, mais il ne semble malheureusement pas travailler. Voici quelques exemples de 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()
La sortie de ce code est:
DEBUG:root:Main process started DEBUG:root:W-1 Started DEBUG:root:W-2 Started DEBUG:root:Main process terminated
Je pense que la W.run.log_terminate()
serait appelée lorsque a.terminate()
et b.terminate()
sont appelés, et la sortie à quelque chose likeso (nous soulignons):
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
Pourquoi est-ce pas de travail, et est-il une meilleure façon de se connecter un message (à partir du contexte de Process
) lorsqu'une Process
est terminée?
Merci pour votre entrée - il est très apprécié
.Solution
EDIT: Sur la base de la solution proposée par Alex Martelli, les travaux suivants comme prévu:
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()
Il vaut la peine de noter le commentaire suivant dans la documentation atexit
:
Note: les fonctions enregistrées via ce module ne sont pas appelés lorsque le programme est tué par un signal, lorsqu'une erreur interne fatale Python est détectée, ou lorsque os._exit () est appelée.
La solution
les docs disent
Sur Unix cela se fait à l'aide du SIGTERM signal; sous Windows TerminateProcess () est utilisé. Notez que les gestionnaires de sortie et enfin des clauses, etc., ne seront pas exécutée.
Si vous êtes sous Unix, vous devriez être en mesure d'intercepter SIGTERM
avec