Я пытаюсь использовать atexit
в a Process
, но к сожалению это, кажется, не работает. Вот некоторый пример кода:
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()
Вывод этого кода:
DEBUG:root:Main process started DEBUG:root:W-1 Started DEBUG:root:W-2 Started DEBUG:root:Main process terminated
Я ожидал бы что W.run.log_terminate()
был бы назван когда a.terminate()
и b.terminate()
названы, и вывод, чтобы быть чем-то likeso (добавленный акцент)!:
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
Почему это не работает и является там лучшим способом зарегистрировать сообщение (от Process
контекст), когда a Process
завершается?
Спасибо за Ваш вход - это очень ценится.
Править: На основе решения, предложенного Alex Martelli, следующие работы как ожидалось:
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()
Стоит отметить следующий комментарий в atexit
документация:
Примечание: функции, зарегистрированные через этот модуль, не вызваны, когда программа закрыта сигналом, когда Python фатальная внутренняя ошибка обнаруживается, или когда OS. _ выход () называют.
Как сказано в документах ,
В Unix это делается с помощью сигнала SIGTERM ; в Windows используется TerminateProcess () . Обратите внимание, что обработчики выхода, предложения finally и т. Д. Не будут выполняться .
Если вы используете Unix, вы должны иметь возможность перехватывать SIGTERM
с помощью сигнала и выполнять любые необходимые «действия по завершению»; однако я не знаю кроссплатформенного решения.