协程是用户态轻量级执行单元,由程序控制切换;线程是内核态调度单位,由操作系统管理。协程协作式调度、开销低、适合高并发i/o;线程抢占式调度、开销大、可利用多核但受gil限制。
python协程和线程本质不同:协程是用户态的轻量级执行单元,由程序自己控制切换;线程是内核态的调度单位,由操作系统管理。关键区别不在“能不能并发”,而在于“谁在调度、怎么切换、开销在哪、适合什么场景”。
调度方式与控制权不同
线程切换由操作系统决定——比如遇到 I/O 或时间片用完,系统强制暂停当前线程,保存寄存器和栈,再恢复另一个线程。这个过程涉及内核态/用户态切换,开销较大。
协程切换完全由 Python 程序控制——仅在明确的 await 点(如 await asyncio.sleep(1)、await aiohttp.get(url))主动让出控制权,切到下一个协程。没有内核参与,上下文保存在用户空间,毫秒级切换都能做到。
- 线程:操作系统调度,不可预测,有抢占式中断
- 协程:协作式调度,必须显式让出,否则会阻塞整个线程
- 协程不能自动检测普通 time.sleep() 或 CPU 密集操作,必须用 async 兼容版本
I/O 密集型场景下的效率差异
处理大量网络请求、数据库查询、文件读写时,大部分时间花在等待响应上。线程模型下,每个线程都在等 I/O,但线程本身仍占用内存(默认约 1MB 栈空间),1000 个线程就是 1GB 内存;协程共享一个线程,每个协程只占几 KB,轻松启动数万个。
本书将PHP开发与MySQL应用相结合,分别对PHP和MySQL做了深入浅出的分析,不仅介绍PHP和MySQL的一般概念,而且对PHP和MySQL的Web应用做了较全面的阐述,并包括几个经典且实用的例子。 本书是第3版,经过了全面的更新、重写以及扩展,包括PHP5的最新特性——新的对象模型、更好的异常处理和SimpleXML;以及MySQL 5的新特性,例如存储过程和存储引擎。 PHP
- 1000 个 HTTP 请求:用线程池可能卡顿或 OOM;用 asyncio + aiohttp 可单线程高效完成
- 协程真正优势不是“快”,而是“高密度低开销”——同样硬件支持更多并发连接
- 线程在 I/O 等待时也会被挂起,但唤醒、调度、上下文恢复成本远高于协程
共享状态与线程安全问题
多线程共享全局变量,修改时必须加锁(threading.Lock),否则出现竞态条件;协程运行在单一线程内,变量访问天然无锁,但要注意:await 之后的状态可能已被其他协程改写,逻辑上仍需考虑时序依赖。
立即学习“Python免费学习笔记(深入)”;
- 协程不解决逻辑并发安全,只省去锁的系统开销
- asyncio 提供 asyncio.Lock,用于协程间对共享资源的互斥访问
- 若混用线程与协程(如在 executor 中跑 CPU 密集任务),仍需按线程规则加锁
适用边界与组合使用策略
协程不是万能替代品。它无法利用多核 CPU,纯计算任务(如图像处理、数值迭代)用协程反而更慢;而线程受 GIL 限制,在 CPU 密集场景也难提速。实际项目中常分层混合使用:
- I/O 主干用协程(asyncio + httpx/aiofiles)——应对高并发请求
- CPU 密集子任务扔进 ProcessPoolExecutor——绕过 GIL,真正并行
- 遗留同步库(如 requests)可通过 loop.run_in_executor桥接进异步流程
- 避免在协程里调用阻塞函数(如 time.sleep、requests.get),否则整条线程卡死









