Python processo non chiamerà atexit
-
23-09-2019 - |
Domanda
Sto cercando di utilizzare atexit
in un Process
, ma purtroppo non sembra funzionare. Ecco qualche esempio di codice:
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()
L'output di questo codice è:
DEBUG:root:Main process started DEBUG:root:W-1 Started DEBUG:root:W-2 Started DEBUG:root:Main process terminated
mi aspetterei che il W.run.log_terminate()
sarebbe chiamato quando a.terminate()
e b.terminate()
sono chiamati, e l'uscita di essere qualcosa likeso (enfasi aggiunta):
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
Perché non è questo lavoro, e c'è un modo migliore per registrare un messaggio (dal contesto Process
) quando un Process
è terminato?
Grazie per l'ingresso - è molto apprezzato
.Soluzione
EDIT: Sulla base di soluzione suggerita da Alex Martelli, le seguenti opere come previsto:
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()
E 'utile sottolineare il seguente commento nella documentazione atexit
:
Nota: le funzioni registrate tramite questo modulo non vengono chiamati quando il programma viene ucciso da un segnale, quando viene rilevato un errore fatale in Python, o quando os._exit () è chiamato.
Soluzione
la documentazione dicono,
In Unix questo viene fatto utilizzando il SIGTERM segnale; su Windows TerminateProcess () viene utilizzato. Si noti che i gestori di uscita e infine clausole, ecc, non sarà eseguito.
Se sei su Unix, si dovrebbe essere in grado SIGTERM
intercetta con segnale , ed eseguire qualunque 'attività di terminazione' è necessario; tuttavia, non so di una soluzione cross-platform.