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

Flask Web应用后台任务执行行为不一致问题排查

问题原因排查与解决方案

核心问题1:Flask Debug模式导致重复启动后台任务

你的代码启用了app.run(debug=True),Flask的Debug模式默认会启动两个进程:主进程和用于代码自动重载的监控进程。这两个进程都会执行if __name__ == '__main__':块内的代码,导致手动创建的t1线程被重复启动,多个writemotiondata线程同时运行,最终出现同一时间间隔内任务多次执行、计数器跳增的情况。

核心问题2:数据库更新非原子操作(次要但需修复)

当前代码采用"先查询计数器值→加1→再更新"的逻辑,属于非原子操作。即使解决了多线程问题,后续若出现并发场景,这种操作会引发竞态条件:多个请求同时读取到同一个旧值,最终导致计数更新异常。


修复步骤

1. 避免Debug模式重复启动线程

若需保留Debug模式,修改入口代码,利用环境变量判断仅在主进程启动线程:

if __name__ == '__main__':
    import os
    # 仅主进程启动后台线程,规避Debug重载进程重复执行
    if not os.environ.get('WERKZEUG_RUN_MAIN'):
        t1 = threading.Thread(target=writemotiondata)
        t1.start()
    app.run(debug=True)

生产环境直接关闭Debug模式:

app.run(debug=False)

2. 改为原子性数据库更新

将查询后更新的逻辑替换为MongoDB的原子递增操作,彻底避免竞态条件:

# 替换原有的计数器更新代码
filter = {"sensorname": "pir"}
# $inc实现原子递增,upsert=True自动插入初始值(无数据时插入numberofpeople=1)
updateddata = {"$inc": {"numberofpeople": 1}}
motiondata.update_one(filter, updateddata, upsert=True)

此操作无需先查询数据,单步完成插入或递增,完全避免计数错误。

3. 优化API连接逻辑

当前每次循环都重新创建API连接,浪费资源且可能引发连接过载,将连接逻辑移到循环外:

def writemotiondata():
    deviceid = 'eb4f7839b63063bdec3ikc'
    openapi = authorization()
    openapi.connect()
    while True:
        response = openapi.get("/v1.0/devices/{}".format(deviceid))
        # 后续业务逻辑不变...

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:22:53