Proceso de Python no llamará atexit
-
23-09-2019 - |
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
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.