Pregunta

Estoy tratando de utilizar atexit en un Process, pero por desgracia, no parece trabajo. Aquí hay un código de ejemplo:

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 salida de este código es:

DEBUG:root:Main process started
DEBUG:root:W-1 Started
DEBUG:root:W-2 Started
DEBUG:root:Main process terminated

Yo esperaría que el W.run.log_terminate() sería llamado cuando a.terminate() y b.terminate() son llamados, y que la salida sea algo likeso (énfasis añadido):

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

¿Por qué no es este trabajo, y es que hay una mejor manera de registrar un mensaje (a partir del contexto Process) cuando se termina un Process?

Gracias por su entrada - es muy apreciada

.

Solución

EDIT: Basado en solución sugerida por Alex Martelli, las siguientes obras como se esperaba:

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()

Vale la pena tener en cuenta el siguiente comentario en la documentación atexit:

Nota:. Las funciones registradas a través de este módulo no son llamados cuando el programa es matado por una señal, cuando se detecta un error interno fatal Python, o cuando os._exit () se llama
¿Fue útil?

Solución

los documentos decir,

  

En Unix esto se hace mediante el SIGTERM   señal; TerminateProcess en Windows ()   se utiliza. Tenga en cuenta que los manipuladores de salida y   Finalmente cláusulas, etc., no serán   ejecutado.

Si está en Unix, usted debería ser capaz de interceptar SIGTERM con señal de , y llevar a cabo actividades que sea 'terminación' que necesita; Sin embargo, no sé de una solución multiplataforma.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top