4

我有一段 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

实际代码远比这段代码复杂,但结构是相同的:即 main 函数保持一个无限循环。

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

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

4

1 回答 1

12

好吧,根据文档,如果程序被 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()的情况下只调用一次。如果需要,您可以安装更多信号处理程序(例如 for等)。如果您需要“更优雅的关闭”,您应该找到一种方法来优雅地中断循环和/或安装外部“关闭处理程序”(以防您没有机会干净地释放资源)或者只是让您的应用程序是TERMINTRCtrl-CHUPSIGKILL

于 2014-05-05T08:51:53.493 回答