
Dash 在 debug 模式下会自动重启应用,导致主脚本执行两次,从而意外创建多个后台线程;关闭 debug 模式或启用 reloader=False 可彻底解决该问题。
dash 在 debug 模式下会自动重启应用,导致主脚本执行两次,从而意外创建多个后台线程;关闭 debug 模式或启用 reloader=false 可彻底解决该问题。
Dash 默认启用的调试模式(debug=True)包含热重载(reloader)机制:Flask 启动时会 fork 一个监控进程,同时运行主应用进程和文件监听进程,因此整个 Python 脚本会被执行两次——这正是你看到 "Load script" 打印两次、两个独立线程并发运行的根本原因。
最直接的修复方式是禁用调试重载功能。推荐以下两种安全方案:
✅ 方案一:关闭 debug 模式(生产就绪)
if __name__ == "__main__":
app = Dash("App")
app.layout = html.Div([html.Div(id='dummy')])
# 确保仅启动一次工作线程
worker_thread = Thread(target=worker, daemon=True) # 推荐设为 daemon
worker_thread.start()
app.run(debug=False) # 关键:禁用 debug 模式
✅ 方案二:保留 debug 功能但禁用重载(开发友好)
if __name__ == "__main__":
app = Dash("App")
app.layout = html.Div([html.Div(id='dummy')])
worker_thread = Thread(target=worker, daemon=True)
worker_thread.start()
# 保留 debug UI,但禁用自动重载,避免二次执行
app.run(debug=True, dev_tools_hot_reload=False, reloader_type="none")
⚠️ 重要注意事项:
- 始终将后台线程设为
daemon=True(如示例所示),防止主线程退出后子线程持续占用资源; - 切勿在
app.layout或回调函数中启动线程——这些代码可能被反复调用;线程初始化必须严格限定在if __name__ == "__main__":块内; - 若使用 Gunicorn/Uvicorn 部署,请确保 WSGI/ASGI 入口不触发重复初始化逻辑;
- 调试时可通过
print(f"PID: {os.getpid()}, Thread ID: {threading.get_ident()}")辅助验证进程与线程唯一性。
通过合理配置运行参数,即可确保后台任务稳定、单例运行,兼顾开发效率与程序健壮性。










