【问题标题】:How to capture ctrl-c for killing a Flask python script如何捕获 ctrl-c 以杀死 Flask python 脚本
【发布时间】:2017-12-05 21:30:56
【问题描述】:

我有以下脚本,它只是启动一个为动态创建的网站提供服务的网络服务器。为了获取动态数据,脚本会打开一个文件来读取数据。

我关心的是如何捕获 CTRL-C 命令来杀死 python 脚本,这样我就可以在脚本线程被杀死之前关闭文件。

我尝试了以下几件事,但都没有成功:

from flask import Flask, render_template
import time

# Initialize the Flask application
app = Flask(__name__)

fileNames = {}
fileDesc = {}
for idx in range(1,4):
    fileNames["name{}".format(idx)] = "./name" + str(idx) + ".txt"
    fileDesc["name{}".format(idx)] = open(fileNames["name{}".format(idx)],'r')

try:
    @app.route('/')
    def index():
        # code for reading data from files
        return render_template('index.html', var1 = var1)

    @app.errorhandler(Exception)
    def all_exception_handler(error):
        print("Closing")
        for key, value in fileDesc:
            val.close()
        print("Files closed")


    if __name__ == '__main__':
        app.run(
            host="192.168.0.166",
            port=int("8080"),
            debug=True
        )

except KeyboardInterrupt:
    print("Closing")
    for key, value in fileDesc:
        val.close()
    print("Files closed")

提前致谢。

【问题讨论】:

  • KeyboardInterrupts 在 python2 中不能按预期工作。你在什么蟒蛇上?
  • 您也可以尝试使用信号。阅读this
  • @cᴏʟᴅsᴘᴇᴇᴅ 我正在使用 Python3。
  • 奇数。它应该工作。您可以尝试@idjaw 提到的信号处理程序。
  • @idjaw 我会检查你的链接。但是在本地应用程序的python中,它非常简单,我已经成功了,但是使用Flask就更复杂了。不知道是因为它停止线程还是什么。但我也会检查信号处理程序

标签: python exception flask try-catch copy-paste


【解决方案1】:

我在我的项目中遇到同样的事情。对我有用的是使用signal 来捕获 CTRL-C。

import sys
import signal
def handler(signal, frame):
  print('CTRL-C pressed!')
  sys.exit(0)
signal.signal(signal.SIGINT, handler)
signal.pause()

将这段代码放入运行 Flask 应用程序的脚本中时,可以捕获 CTRL-C。到目前为止,您必须使用 CTRL-C 两次,然后执行处理程序。如果我发现新的东西,我会进一步调查并编辑答案。

编辑 1

好的,我做了更多的研究并想出了一些其他的方法,因为上面的方法很简单。

在生产环境中,诸如关闭数据库或文件之类的清理代码是通过 @app.teardown_appcontext 装饰器完成的。见this part of the tutorial

在使用简单服务器时,您可以通过暴露 werkzeug 关闭功能将其关闭。见this post

编辑 2

我已经测试了 Werkzeug 关闭功能,它还可以与 teardown_appcontext 功能一起使用。所以我建议使用装饰器编写你的拆卸函数,并编写一个简单的函数来关闭 werkzeug 服务器。这样生产和开发代码是相同的。

【讨论】:

  • 您能否详细说明解决方案?我也对这种代码感兴趣,因为我正在运行一个带有烧瓶加 socketio 和后台进程的应用程序,当烧瓶关闭时需要关闭这些进程
  • 来自:this question 这对于 Windows 来说不是一个可行的解决方案
  • signal.pause() 这行是干什么用的?
  • 它会导致信号进程休眠,直到收到信号(在本例中为终止信号)docs.python.org/3/library/signal.html#signal.pause 否则您将处于休眠状态并阻塞进程。
猜你喜欢
  • 2021-12-15
  • 2015-04-17
  • 2017-03-31
  • 2023-03-18
  • 2021-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多