Процесс Python не назовет atexit

Я пытаюсь использовать 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. _ выход () называют.

20
задан Brian M. Hunt 30 March 2010 в 20:16
поделиться

1 ответ

Как сказано в документах ,

В Unix это делается с помощью сигнала SIGTERM ; в Windows используется TerminateProcess () . Обратите внимание, что обработчики выхода, предложения finally и т. Д. Не будут выполняться .

Если вы используете Unix, вы должны иметь возможность перехватывать SIGTERM с помощью сигнала и выполнять любые необходимые «действия по завершению»; однако я не знаю кроссплатформенного решения.

18
ответ дан 30 November 2019 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: