program python multiprocessing terminate atexit

program - atexit python



El proceso de Python no llamarĂ¡ atexit (1)

Como dicen los doctores ,

En Unix esto se hace usando la señal SIGTERM; en Windows se utiliza TerminateProcess (). Tenga en cuenta que los manejadores de salida y las cláusulas finales, etc., no se ejecutarán.

Si estás en Unix, deberías poder interceptar el SIGTERM con la signal y realizar las "actividades de terminación" que necesites; Sin embargo, no sé de una solución multiplataforma.

Estoy tratando de usar atexit en un Process , pero desafortunadamente no parece funcionar. 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

Espero que se W.run.log_terminate() cuando se a.terminate() y b.terminate() , y la salida sea algo como like (¡énfasis agregado) !:

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 funciona esto y hay una mejor manera de registrar un mensaje (desde el contexto del Process ) cuando se termina un Process ?

Gracias por su aporte, es muy apreciado.

Solución

EDIT: Basado en la solución sugerida por Alex Martelli, los siguientes trabajos como se espera:

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 anotar el siguiente comentario en la documentación de atexit :

Nota: las funciones registradas a través de este módulo no se llaman cuando el programa es eliminado por una señal, cuando se detecta un error interno fatal de Python, o cuando se llama a os._exit ().