在FastAPI+Uvicorn中运行独立子进程的问题求助
让FastAPI中启动的子进程完全脱离Uvicorn进程
要让子进程彻底独立于Uvicorn进程,需要从进程隔离、IO重定向和避免请求阻塞三个维度处理,以下是具体实现方案:
核心思路
- 用
subprocess.Popen替代subprocess.run:run会阻塞当前请求直到子进程执行完毕,而Popen是异步启动子进程,不会拖慢接口响应速度。 - 脱离父进程的会话/进程组:防止Uvicorn退出时,操作系统向子进程发送终止信号。
- 重定向标准输入输出:避免子进程占用Uvicorn的终端IO,防止子进程因等待输入挂起,同时避免干扰Uvicorn的日志输出。
跨平台实现代码
from fastapi import FastAPI import subprocess import os import sys app = FastAPI() def start_independent_process(command): # 配置子进程隔离参数 kwargs = {} if sys.platform == "win32": # Windows平台:创建新进程组,脱离父进程控制 kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP else: # Linux/macOS平台:创建新会话,脱离终端绑定 kwargs["start_new_session"] = True # 重定向标准输入输出到空设备,避免干扰Uvicorn日志或子进程挂起 dev_null = open(os.devnull, 'w') kwargs.update({ "stdin": dev_null, "stdout": dev_null, "stderr": dev_null, "close_fds": True # 关闭子进程继承的所有文件描述符,强化隔离 }) # 异步启动子进程 subprocess.Popen(command, **kwargs) dev_null.close() @app.get('/') def index(): # 触发独立子进程启动 start_independent_process(['python', 'target_script.py', 'arg1', 'arg2']) return {"status": "子进程已独立启动"} if __name__ == '__main__': from uvicorn import run run(app, port=80)
关键参数说明
start_new_session=True(Linux/macOS):为子进程创建新的会话,使其成为会话首进程,彻底脱离原父进程的会话和终端,Uvicorn退出时不会对其产生影响。creationflags=subprocess.CREATE_NEW_PROCESS_GROUP(Windows):为子进程创建独立进程组,避免父进程的终止信号传递给子进程。close_fds=True:关闭子进程从父进程继承的所有文件描述符,进一步切断父子进程的资源关联。- IO重定向到
os.devnull:屏蔽子进程的输入输出,防止其输出混入Uvicorn日志,同时避免子进程因等待标准输入而阻塞。
验证方式
- 启动FastAPI应用后,访问触发子进程的接口。
- 查看系统进程列表(Linux用
ps aux,Windows用任务管理器),确认target_script.py的父进程ID不是Uvicorn的进程ID。 - 停止Uvicorn进程,再次查看进程列表,确认子进程仍在运行。
内容的提问来源于stack exchange,提问作者user23470475
相关产品推荐
相关产品推荐

