Python Flask:请求过程中更新倒计时变量问题求助
解决Flask倒计时请求冲突问题
这个问题的核心是你的Flask应用在每个请求中同步执行倒计时逻辑,再加上Flask开发服务器默认的多线程特性,导致多个请求会同时运行各自的倒计时进程,互相干扰。要解决这个问题,我们需要把倒计时放到后台线程运行,并且维护一个全局的状态来控制旧倒计时停止、启动新倒计时。
下面是修改后的完整代码,我会逐步解释关键改动:
from flask import Flask, request import time import threading app = Flask(__name__) # 全局变量:跟踪当前倒计时线程和停止信号事件 current_countdown_thread = None stop_countdown_event = threading.Event() def countdown(speed, thetime, cents): print('\n') print('AccuView Digital:') print('Speed:', speed,' Time:', thetime,' Cents:', cents) print('-------------------------------') remaining_time = int(thetime) # 循环条件增加:检查是否收到停止信号 while remaining_time > 0 and not stop_countdown_event.is_set(): mins, secs = divmod(remaining_time, 60) timer = '{:02d}:{:02d}'.format(mins, secs) print('Tijd:', timer, end="\r") time.sleep((speed + 1) / 1000) remaining_time -= 1 # 只有正常结束倒计时(不是被强制停止)才输出提示 if not stop_countdown_event.is_set(): print('Werp geld in\n') # 重置停止事件,为下一次倒计时做准备 stop_countdown_event.clear() @app.route('/', methods=["GET"]) def handle_request(): global current_countdown_thread, stop_countdown_event # 先检查请求参数是否完整,避免KeyError try: speed = float(request.args["speed"]) thetime = request.args["time"] cents = request.args["cents"] except KeyError: return 'Missing required parameters (speed/time/cents)', 400 # 如果当前有正在运行的倒计时,先停止它 if current_countdown_thread is not None and current_countdown_thread.is_alive(): stop_countdown_event.set() # 发送停止信号 # 等待旧线程结束,设置1秒超时避免卡住 current_countdown_thread.join(timeout=1) # 创建并启动新的倒计时后台线程 current_countdown_thread = threading.Thread( target=countdown, args=(speed, thetime, cents) ) current_countdown_thread.start() return '1' if __name__ == '__main__': app.run(host='192.168.1.107', port=8090, threaded=True)
关键改动说明:
- 引入线程模块:用
threading把倒计时逻辑放到后台线程运行,这样请求可以立即返回响应,不会被同步逻辑阻塞。 - 全局状态控制:
current_countdown_thread:保存当前正在运行的倒计时线程实例,方便后续检查和停止。stop_countdown_event:线程安全的事件对象,用来给旧倒计时线程发送停止信号,避免强制终止线程带来的问题。
- 修改倒计时函数:在循环中增加
stop_countdown_event.is_set()的检查,一旦收到停止信号就立即退出循环,终止倒计时。 - 请求处理逻辑优化:
- 新增参数校验,避免缺少参数导致的崩溃。
- 每次新请求到来时,先检查是否有活跃的旧线程,若有则发送停止信号并等待其结束,再启动新的倒计时线程。
- 显式开启多线程:虽然Flask开发服务器默认开启多线程,但显式设置
threaded=True让配置更清晰。
注意事项:
- 这里的全局变量在单进程服务器环境下是有效的,如果后续部署到多进程服务器(比如Gunicorn多进程模式),需要用更全局的存储(比如Redis)来维护状态,不过对于你的开发场景,当前方案完全够用。
join(timeout=1)设置了1秒超时,是为了避免旧线程因为某些原因卡住,导致新请求长时间等待。
内容的提问来源于stack exchange,提问作者user3014636
相关产品推荐
相关产品推荐

