FastAPI中线程重复触发目标函数的问题解决方案咨询
解决FastAPI初始化时线程重复执行的问题
你遇到的问题根源是开发模式下FastAPI的自动重载机制:当用uvicorn以--reload参数启动应用时,会启动两个进程——一个负责监听文件变化的主进程,一个实际处理请求的工作进程。你的__init_application()函数会被这两个进程各自执行一次,导致线程被重复启动,test_ack函数也就多次运行,输出异常。
下面是几种可行的解决方法:
方案1:使用FastAPI启动事件(推荐)
FastAPI内置的startup事件装饰器会在应用真正启动、开始处理请求前执行一次,且只会在工作进程中触发,完美避免重载时的重复执行。把线程启动逻辑放到这个事件里:
from fastapi import FastAPI import threading app = FastAPI(title="Test", version="0.1") def test_ack(): var = 0 while True: if var > 5: break var += 1 print(var) @app.on_event("startup") def startup_event(): feedback_ack = threading.Thread(target=test_ack) feedback_ack.daemon = True # 设置为守护线程,应用关闭时自动终止 feedback_ack.start()
方案2:检测进程环境,避免重复启动
如果坚持要在初始化函数里启动线程,可以通过判断uvicorn重载模式的环境变量,只在主进程中启动线程:
from fastapi import FastAPI import threading import os def __init_application(): app = FastAPI(title="Test", version="0.1") # 仅在非重载的主进程中启动线程 if not os.environ.get("UVICORN_RELOADER"): feedback_ack = threading.Thread(target=test_ack) feedback_ack.daemon = True feedback_ack.start() return app api_app = __init_application() def test_ack(): var = 0 while True: if var > 5: break var += 1 print(var)
方案3:关闭自动重载模式
如果开发时不需要热重载功能,启动应用时去掉--reload参数即可:
uvicorn main:api_app
这样只会启动一个进程,__init_application()仅执行一次,线程也就只会启动一次。
内容的提问来源于stack exchange,提问作者praveen jp
相关产品推荐
相关产品推荐

