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
.
Était-ce utile?

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

scroll top