一尘不染

Python进程不会调用atexit

python

我试图用atexit一个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:W-1已开始
DEBUG:root:W-2已开始
DEBUG:root:主进程终止

我希望W.run.log_terminate()可以在a.terminate()和被调用时b.terminate()调用,并且输出将类似于(强调)!:

调试:根:主进程已启动
DEBUG:root:W-1已开始
DEBUG:root:W-2已开始
**调试:root:W-1终止!
调试:root:W-2已终止!**
DEBUG:root:主进程终止

为什么这不起作用,并且Process当aProcess终止时是否有更好的方法(从上下文)记录消息?

感谢您的输入-非常感谢。

编辑: 根据亚历克斯·马特利(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](http://docs.python.org/library/atexit.html)文档中注意以下注释:

注意:当程序被信号杀死,检测到Python致命内部错误或调用os._exit()时,不会调用通过此模块注册的功能。


阅读 181

收藏
2021-01-20

共1个答案

一尘不染

正如文档所说,

在Unix上,这是使用SIGTERM信号完成的。在Windows上使用TerminateProcess()。注意,退出处理程序和finally子句等将不会执行。

如果您使用的是Unix,则应该能够SIGTERM使用signal进行拦截,并执行所需的任何“终止活动”;但是,我不知道跨平台的解决方案。

2021-01-20