You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让BackgroundScheduler更新的变量在Flask页面刷新时生效?

问题原因

Flask开发服务器默认开启多线程/多进程模式,定时任务运行的线程/进程与处理HTTP请求的线程/进程内存空间相互隔离。你在定时任务里更新的current_time是当前线程/进程内的副本,而请求线程读取的是另一个线程/进程里的初始值,所以页面始终显示0。

解决方案

1. 调试阶段:单线程运行Flask(仅用于临时验证)

强制Flask用单线程运行,让定时任务和请求线程共享同一块内存:

  • 命令行启动:
    flask run --threaded=False
    
  • 或者代码里指定:
    if __name__ == '__main__':
        app.run(threaded=False)
    
    注意:这种方式不适合生产环境,会严重影响并发性能。

2. 生产环境:用共享存储替代全局变量

把需要定时更新的变量存在所有进程/线程都能访问到的共享存储里,比如Redis、内存数据库或文件。以下是Redis实现的示例:

步骤1:安装依赖

pip install redis

步骤2:修改代码

from flask import Flask, render_template
from apscheduler.schedulers.background import BackgroundScheduler
import redis
import datetime

app = Flask(__name__)
# 连接本地Redis服务,根据实际情况修改地址端口
redis_client = redis.Redis(host='localhost', port=6379, db=0)

# 初始化变量值
redis_client.set('current_time', '0')

def job1():
    now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    print(f"定时任务执行:{now}")
    # 把最新时间写入Redis
    redis_client.set('current_time', now)

# 配置并启动定时任务
scheduler = BackgroundScheduler()
scheduler.add_job(job1, 'interval', seconds=5)
scheduler.start()

@app.route('/')
def index():
    # 从Redis读取最新时间
    current_time = redis_client.get('current_time').decode('utf-8')
    return render_template('index.html', current_time=current_time)

if __name__ == '__main__':
    app.run()

模板文件(index.html)

<!DOCTYPE html>
<html>
<head>
    <title>实时时间展示</title>
</head>
<body>
    <h1>当前时间:{{ current_time }}</h1>
</body>
</html>

3. 进阶方案:用Celery实现分布式定时任务

如果你的实际业务逻辑复杂,建议用Celery搭配Redis/RabbitMQ做任务队列和定时调度,避免多进程环境下重复启动调度器的问题,同时支持更复杂的任务场景。


内容的提问来源于stack exchange,提问作者Total30

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 22:52:32