【问题标题】:The invocation of signal handler and atexit handler in PythonPython中信号处理程序和atexit处理程序的调用
【发布时间】:2014-05-05 08:27:55
【问题描述】:

我有一段 Python 代码如下:

import sys
import signal
import atexit

def release():
    print "Release resources..."

def sigHandler(signo, frame):
    release()
    sys.exit(0)

if __name__ == "__main__":
    signal.signal(signal.SIGTERM, sigHandler)
    atexit.register(release)

    while True:
        pass

真正的代码远比这个sn-ps复杂,但结构是一样的:即main函数保持一个无限循环。

我需要一个信号回调来释放占用的资源,比如数据库句柄。 然后我添加一个SIGTERM 处理程序,以防服务器被杀死,它只是调用释放函数然后退出进程。 atexit 旨在成功完成处理过程。

现在我有一个问题,我只想在进程被终止时调用 release 一次。我的代码有什么改进吗?

【问题讨论】:

  • 我想问一下是否真的有必要以这种方式退出main中的循环而优雅地关闭?
  • 一个广泛使用的习惯用法是检查我们是否应该打破循环然后明确释放资源。
  • @user3159253 您好,感谢您的快速回复。我想是的,主循环实际上是一个http服务器模块,我自己无权中断循环。只有 Ctrl-C 可以阻止它。是的,它的名字是瓶子T_T。

标签: python signals atexit


【解决方案1】:

好吧,根据documentation,如果程序被 Python 未处理的信号杀死,或者发生内部错误,或者调用了os._exit(),则不会执行 atexit 处理程序。所以我会使用这样的东西(几乎复制了你的代码):

import sys
import signal
import atexit

def release():
    print "Release resources..."

def sigHandler(signo, frame):
    sys.exit(0)

if __name__ == "__main__":
    atexit.register(release)
    signal.signal(signal.SIGTERM, sigHandler)

    while True:
        pass

我已经检查过release() 被调用一次且仅在TERM(外部发出)和INTR 信号(来自键盘的Ctrl-C)的情况下被调用。如果需要,您可以安装更多信号处理程序(例如,HUP 等)。如果您需要“更优雅的关闭”,您应该找到一种方法来优雅地中断循环和/或安装外部“关闭处理程序”(在SIGKILL 的情况下,您将没有机会干净地释放资源)或干脆将您的应用程序设为ACID

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多