0

0

解决 FastAPI 异步路由中无限循环导致的死锁问题

碧海醫心

碧海醫心

发布时间:2025-09-24 22:12:01

|

612人浏览过

|

来源于php中文网

原创

解决 fastapi 异步路由中无限循环导致的死锁问题

在 FastAPI 应用中,如果需要在异步路由中执行无限循环,直接使用 while True 可能会导致整个应用死锁,其他路由无法响应。这是因为异步函数在执行时,如果没有适当的让出控制权,会阻塞事件循环,导致 FastAPI 无法处理其他请求。下面将介绍两种避免死锁的解决方案。

使用 BackgroundTasks

FastAPI 提供了 BackgroundTasks 类,可以将耗时任务放入后台执行,从而避免阻塞主线程。这种方式非常适合处理无限循环任务。

from fastapi import FastAPI, BackgroundTasks
import random

app = FastAPI()

@app.get("/hello")
async def hello():
    return {"Hello": "World"}

@app.get("/normal")
def route_normal():
    while True:
        print({"route_normal": random.randint(0, 10)})

@app.get("/async")
async def route_async(background_tasks: BackgroundTasks):
    def background_task():
        while True:
            print({"route_async": random.randint(0, 10)})

    background_tasks.add_task(background_task)
    return {"message": "Background task started"}

代码解释:

  1. 导入 BackgroundTasks 类。
  2. 在异步路由 route_async 中,声明一个 background_tasks 参数,类型为 BackgroundTasks。FastAPI 会自动注入该对象。
  3. 定义一个 background_task 函数,其中包含无限循环。
  4. 使用 background_tasks.add_task() 将 background_task 函数添加到后台任务队列。
  5. 路由函数立即返回一个消息,表示后台任务已启动。

注意事项:

  • 后台任务的执行与主线程是并发的,因此需要注意线程安全问题。
  • BackgroundTasks 适用于执行不需要立即返回结果的任务。

使用 asyncio.sleep()

另一种解决方案是在无限循环中加入 asyncio.sleep(),让出控制权,允许事件循环处理其他任务。

Action Figure AI
Action Figure AI

借助Action Figure AI的先进技术,瞬间将照片转化为定制动作人偶。

下载
import asyncio
from fastapi import FastAPI
import random

app = FastAPI()

@app.get("/hello")
async def hello():
    return {"Hello": "World"}

@app.get("/normal")
def route_normal():
    while True:
        print({"route_normal": random.randint(0, 10)})

@app.get("/async")
async def route_async():
    while True:
        await asyncio.sleep(0) # do a sleep here so that the main thread can do its magic, at least once per loop, changing the sleep duration will allow the main thread to process other threads longer, please read up more on the specifics
        print({"route_async": random.randint(0, 10)})

代码解释:

  1. 导入 asyncio 模块。
  2. 在异步路由 route_async 的无限循环中,使用 await asyncio.sleep(0) 让出控制权。

注意事项:

  • asyncio.sleep(0) 会立即让出控制权,允许事件循环处理其他任务。
  • 可以调整 asyncio.sleep() 的参数,控制让出控制权的时间。参数越大,其他任务获得执行的机会越多,但当前任务的执行速度会降低。
  • 这种方法适用于对实时性要求不高的任务。

总结

在 FastAPI 异步路由中使用无限循环时,需要特别注意避免阻塞事件循环。使用 BackgroundTasks 可以将任务放入后台执行,而使用 asyncio.sleep() 可以让出控制权。选择哪种方案取决于具体的应用场景和需求。如果任务不需要立即返回结果,且对实时性要求不高,建议使用 BackgroundTasks。如果需要在循环中进行一些操作,且对实时性有一定的要求,可以使用 asyncio.sleep()。

相关文章

路由优化大师
路由优化大师

路由优化大师是一款及简单的路由器设置管理软件,其主要功能是一键设置优化路由、屏广告、防蹭网、路由器全面检测及高级设置等,有需要的小伙伴快来保存下载体验吧!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Python FastAPI异步API开发_Python怎么用FastAPI构建异步API
Python FastAPI异步API开发_Python怎么用FastAPI构建异步API

Python FastAPI 异步开发利用 async/await 关键字,通过定义异步视图函数、使用异步数据库库 (如 databases)、异步 HTTP 客户端 (如 httpx),并结合后台任务队列(如 Celery)和异步依赖项,实现高效的 I/O 密集型 API,显著提升吞吐量和响应速度,尤其适用于处理数据库查询、网络请求等耗时操作,无需阻塞主线程。

26

2025.12.22

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

84

2023.09.25

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

480

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

480

2023.08.10

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

1

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

5

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

6

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

5

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 45.6万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号