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

在FastAPI+Uvicorn中运行独立子进程的问题求助

让FastAPI中启动的子进程完全脱离Uvicorn进程

要让子进程彻底独立于Uvicorn进程,需要从进程隔离、IO重定向和避免请求阻塞三个维度处理,以下是具体实现方案:

核心思路

  1. 用subprocess.Popen替代subprocess.run:run会阻塞当前请求直到子进程执行完毕,而Popen是异步启动子进程,不会拖慢接口响应速度。
  2. 脱离父进程的会话/进程组:防止Uvicorn退出时,操作系统向子进程发送终止信号。
  3. 重定向标准输入输出:避免子进程占用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日志,同时避免子进程因等待标准输入而阻塞。

验证方式

  1. 启动FastAPI应用后,访问触发子进程的接口。
  2. 查看系统进程列表(Linux用ps aux,Windows用任务管理器),确认target_script.py的父进程ID不是Uvicorn的进程ID。
  3. 停止Uvicorn进程,再次查看进程列表,确认子进程仍在运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 01:12:05