AI项目博客
记录 AI 工程实践与大模型应用

FastAPI & SQLAlchemy 实战(一):线程、进程、协程,到底差在哪

「FastAPI & SQLAlchemy 实战」系列共 10 篇,从协程基础讲到数据库接口。这是第 1 篇。

结论:I/O 密集型任务优先用协程,CPU 密集型任务用多进程,线程只适合少量阻塞调用或必须使用同步库的场景。

一、三者怎么选

进程 线程 协程
调度者 操作系统 操作系统 程序自己(事件循环)
内存 独立地址空间 共享进程内存 共享线程内存
切换成本 高 中 极低
并发量 几十个 几百到几千 几万
适合 CPU 密集 少量阻塞 I/O 高并发 I/O

二、线程为什么扛不住高并发 I/O

  • 切换开销:几千个线程之间切换,CPU 大量时间花在上下文切换上;
  • 同步复杂:共享内存需要锁,锁用不好就死锁;
  • 阻塞浪费:线程等待网络时被挂起,但线程本身仍占资源,创建数量也有上限。

三、协程的优势

  • 由程序自己调度,await 时主动让出 CPU;
  • 创建成本低,一个线程可以挂几万个协程;
  • 同一时刻只有一个协程在跑,不需要锁保护共享数据;
  • 等待 I/O 时切换到其他协程,不浪费 CPU。

注意:协程是单线程并发,不是并行。CPU 密集型任务不会因为用了协程就变快。

四、一个直观对比

10 个网络请求,每个耗时 1 秒:

  • 串行 await:约 10 秒;
  • 线程池:受池大小限制,通常 1–2 秒,但线程数有上限;
  • 协程并发:约 1 秒,几千个请求也能挂在同一个线程上。
# 线程:每个请求占一个线程
# 协程:等待 I/O 时让出,事件循环去跑其他协程

五、什么时候别用协程

  • CPU 密集:用多进程,协程帮不上忙;
  • 必须用同步库(requests、pymysql):它会阻塞整个事件循环,用 asyncio.to_thread() 隔离;
  • 任务之间有大量共享状态:协程虽然不用锁,但逻辑复杂度不一定低。

六、选择顺序

  1. CPU 密集 → 多进程;
  2. I/O 密集且有异步库 → 协程;
  3. I/O 密集但只有同步库 → 线程池,或用 asyncio.to_thread 隔离。
# 错误:async def 里 time.sleep(1),整个事件循环停 1 秒
# 正确:await asyncio.sleep(1)

下一篇

下一篇讲 async def、await 和事件循环:协程到底是怎么被调度起来的。

下一篇:async/await 与事件循环

赞(0)
未经允许不得转载:AI项目博客 » FastAPI & SQLAlchemy 实战(一):线程、进程、协程,到底差在哪

评论 抢沙发

AI项目博客

专注 AI 工程化落地 —— 覆盖智能体、大模型、Java AI 与 Python 的学习笔记,以及 AI 平台的项目实战记录。

关于本站文章归档

登录

找回密码

注册