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

FastAPI官方文档的WebSocket示例是否会导致进程死锁?

FastAPI WebSocket 中while True写法的阻塞问题说明

结论:官方示例中的while True写法不会造成进程死锁,服务端可以同时正常响应多个WebSocket连接请求,第二个连接不会被阻塞。

背后运行原理

这种带异步等待的无限循环是长连接场景的标准实现,逻辑和ASGI异步模型的调度规则直接相关:

  • FastAPI是ASGI类框架,通常跑在Uvicorn、Hypercorn这类ASGI服务器上,所有用async def定义的接口都运行在单线程异步事件循环中,靠协程切换实现高并发,不需要为每个连接开独立线程。
  • 示例里的while True不会卡住事件循环:循环内部的await websocket.receive_text()、await websocket.send_text()都是非阻塞的异步IO操作。代码执行到await关键字时,当前连接对应的协程会主动让出CPU执行权,挂起等待对应IO事件触发(比如当前连接收到客户端消息、消息发送完成),挂起状态下不会占用事件循环的处理资源。
  • 协程挂起期间,事件循环可以自由处理其他待执行任务:包括新的WebSocket连接握手、其他已建立连接的消息收发、普通HTTP请求响应等,完全不会被单个连接的无限逻辑阻塞。

实际运行流程

拿两个并发连接的场景拆解执行过程:

  1. 第一个WebSocket连接到达服务端,事件循环调度执行对应端点协程:完成连接握手(await websocket.accept())后进入循环,执行到await websocket.receive_text()时协程挂起,等待该连接的客户端发送消息,执行权交还给事件循环。
  2. 此时第二个连接请求到达,空闲的事件循环立刻调度处理第二个连接的协程:同样完成握手、进入循环、挂起等待消息,整个过程没有任何等待卡顿。
  3. 后续只要任意一个连接收到客户端消息,事件循环就会唤醒对应连接的协程,执行消息回发逻辑,处理完成后协程会再次回到等待收消息的挂起状态,交回执行权。

真正会导致阻塞的错误写法

只有当while True循环里没有任何带await的异步等待,全是同步计算、同步阻塞操作时,才会占住事件循环不释放执行权,导致所有新请求、其他连接的消息都无法处理,比如下面的错误示例:

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    while True:
        # 无await的纯同步死循环,会直接堵死整个事件循环
        calculate_prime_number_forever()

如果把端点写成同步def(不带async关键字)再写无限循环,FastAPI会把整个端点逻辑扔到独立线程中运行,虽然不会堵死主事件循环,但线程池容量有限,连接数多了会耗尽线程资源,无法支撑高并发场景。

官方示例中的写法是行业通用的标准实现,单进程ASGI服务靠这种协程调度模式,可以轻松承载上万条同时在线的WebSocket连接,挂起状态的协程几乎不会额外消耗CPU资源。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:27:13