Python进程不会调用atexit [英] Python Process won't call atexit

查看:532
本文介绍了Python进程不会调用atexit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Process中使用atexit,但是不幸的是它似乎不起作用.这是一些示例代码:

I'm trying to use atexit in a Process, but unfortunately it doesn't seem to work. Here's some example code:

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

我希望在调用a.terminate()b.terminate()时会调用W.run.log_terminate(),并且输出类似(强调)!:

I would expect that the W.run.log_terminate() would be called when a.terminate() and b.terminate() are called, and the output to be something likeso (emphasis added)!:


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终止时是否有更好的方法来记录消息(来自Process上下文)?

Why isn't this working, and is there a better way to log a message (from the Process context) when a Process is terminated?

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

Thank you for your input - it's much appreciated.

根据亚历克斯·马特利(Alex Martelli)提出的解决方案,以下各项按预期工作:

Based on solution suggested by Alex Martelli, the following works as expected:

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文档中注意以下注释:

It's worthwhile to note the following comment in the atexit documentation:

注意:当程序被信号杀死,检测到Python致命内部错误或调用os._exit()时,不会调用通过此模块注册的功能.
Note: the functions registered via this module are not called when the program is killed by a signal, when a Python fatal internal error is detected, or when os._exit() is called.

推荐答案

作为文档说,

在Unix上,这是使用SIGTERM完成的 信号;在Windows TerminateProcess()上 用来.请注意,出口处理程序和 最终条款等将不会 被执行.

On Unix this is done using the SIGTERM signal; on Windows TerminateProcess() is used. Note that exit handlers and finally clauses, etc., will not be executed.

如果您使用的是Unix,则应该可以使用SIGTERM "noreferrer>信号,并执行您需要的任何终止活动";但是,我不知道跨平台的解决方案.

If you're on Unix, you should be able intercept SIGTERM with signal, and perform whatever "termination activities" you need; however, I don't know of a cross-platform solution.

这篇关于Python进程不会调用atexit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆