我有一门课,我想确保正确关闭。特别是,即使我的主进程被外部事件(例如: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)
答案 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))