Próbuję użyć atexit
w Process
, ale niestety to nie działa. Oto niektóre przykładowy kod:Proces w języku Python nie będzie wywoływał atexit
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()
Wyjście z tego kodu jest:
DEBUG:root:Main process started DEBUG:root:W-1 Started DEBUG:root:W-2 Started DEBUG:root:Main process terminated
Spodziewam się, że W.run.log_terminate()
będzie wywoływana, gdy a.terminate()
i b.terminate()
są nazywane, a wyjście będzie coś likeso (kursywa dodana) !:
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
Dlaczego nie jest to pracy i czy istnieje lepszy sposób, aby zalogować się komunikat (od Process
kontekst), gdy kończy się Process
?
Dziękuję za Twój wkład - jest to bardzo cenne.
Rozwiązanie
EDIT: W oparciu o rozwiązanie sugerowane przez Alex Martelli następujące prace zgodnie z oczekiwaniami:
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()
To warto zwrócić uwagę na następujący komentarz w dokumentacji atexit
:
Uwaga: funkcje zarejestrowane za pomocą tego modułu nie są wywoływane, gdy program jest zabijany przez sygnał, gdy wykryty zostanie krytyczny błąd Pythona lub gdy zostanie wywołana funkcja os._exit().