如何保证正确关闭

时间:2017-05-06 14:57:12

标签: python

我有一门课,我想确保正确关闭。特别是,即使我的主进程被外部事件(例如:SIGTERM)杀死,我希望它关闭。

如果“异常”被杀,则不会调用上下文管理器和atexit。所以我一直在尝试使用信号来捕获事件,然后运行我的特定清理代码。

但现在我已经深入了解python如何清理不同类型的出口。例如,虽然我可以捕获signal.SIGTERM并添加我自己的处理程序,但我不知道如何在完成后调用默认处理程序。但是不是专家,让我的库用我自己的代码接管正确的系统退出我感到很不舒服。

(细节:我使用搁架,如果你没有关闭架子,它将保持锁定和不可打开的状态 - 基本上无法使用。)

我这太难了吗?我认为确保我能够正确清理不需要深入的专业知识。

或者,如果我确实需要捕获信号然后接管系统退出,我可以简单地执行清理代码,如果唯一的其他处理程序是SIG_DFL,那么我只是做一个sys.exit()?这听起来有风险,但是可以吗?

我目前的代码:

def reg_sig(signum):
    old_handler = signal.getsignal(signum)

    def sighandler(signum, frame):
        close_open_objects() # <== my custom code
        if callable(old_handler):
            old_handler()
        else:
            # What goes here?
            # do_default_handler() # <- this seems ideal
            # or
            # sys.exit()

    try:
        # I'm not sure what signals might be called so I register a bunch.
        signal.signal(signum, sighandler) 
    except Exception as err:
        pass

# Register signals
for sig in [signal.SIGHUP, signal.SIGINT, signal.SIGQUIT, signal.SIGABRT, 
            signal.SIGKILL,signal.SIGTERM]:
    reg_sig(sig)

1 个答案:

答案 0 :(得分:3)

一个简单的解决方案是使用atexit并注册一个调用sys.exit(0)的信号处理程序。请注意,这会更改过程退出代码,以防信号通常返回。来自a related answer

import sys, atexit, signal
atexit.register(close_open_objects)  # Your custom code
signal.signal(signal.SIGTERM, lambda n, f: sys.exit(0))