我有以下脚本,它只启动一个为动态创建的网站提供服务的网络服务器。为了获取动态数据,脚本打开一个文件来读取数据。
我担心的是如何捕捉 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")
提前致谢。
我在项目中遇到同样的问题。对我有用的东西是使用
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
装饰器完成的。请参阅教程的这一部分。
使用简单服务器时,可以通过暴露 werkzeug 关闭函数来关闭它。见这篇文章.
编辑2
我已经测试了Werkzeug shutdown 功能,它也可以与
teardown_appcontext
功能一起使用。所以我建议使用装饰器编写拆卸函数,并编写一个简单的函数来关闭 werkzeug 服务器。这样生产和开发代码是相同的。
我使用 VScode 运行 flask 应用程序,我遇到了和你一样的事情。 在 VScode 下方的“输出”中,“按 CTRL+C 退出”,但实际上它不起作用,CTRL+SPACE 也是如此。 我的解决办法是
use CTRL+ALT+M instead
。
如果 CTRL+C 在 linux 终端上工作,我认为 CTRL+C 应该有助于交互式终端,如 CMD、PowerShell 或 bash。
VScode的“OUTPUT”区域可能只是一个输出信息的地方。
使用
atexit
来处理这个,来自:https://stackoverflow.com/a/30739397/5782985
import atexit
#defining function to run on shutdown
def close_running_threads():
for thread in the_threads:
thread.join()
print "Threads complete, ready to finish"
#Register the function to be called on exit
atexit.register(close_running_threads)
#start your process
app.run()