问题: 多线程、多进程、多协程,哪个更适合 IO 密集型任务?

👇 点击展开/折叠 面试背诵模板(建议先背这个) IO 密集型任务首选协程,次选多线程,不选多进程。协程由用户态调度,切换无需系统调用,开销极小(纳秒级),单线程内无锁竞争,支持数万并发;多线程在 IO 阻塞时释放 GIL 也能并发,但受系统线程资源限制(通常数千)且上下文切换涉及内核态(微秒级);多进程独立内存,切换开销大且通信需序列化,在 IO 场景无性能增益,反而浪费资源,最不推荐。
---

协程为何是 IO 密集型的首选

协程的切换完全发生在用户态,仅需保存少量寄存器上下文和栈帧,不涉及系统调用,单个协程切换耗时仅数十纳秒。单线程内无需考虑锁竞争,天然避免死锁。依赖事件循环(Event Loop)在单个线程内管理海量任务,遇到 await 阻塞时主动让出,等待 IO 就绪后恢复执行,资源利用率极高。Python 的 asyncio 模块配合 aiohttp、aiomysql 等异步库可轻松支撑数万并发连接。

多线程的实际定位与局限

多线程在 IO 密集型任务中依然可用且有效,因为线程在发起 recv、read 等系统调用时会主动释放 GIL,其他线程可获取锁执行,从而实现并发。但每个线程默认栈约 1MB,系统级线程数量受限(通常数千),且切换需陷入内核态,耗时约数微秒。多个线程竞争共享资源时仍需加锁(如 Lock),增加额外开销。适合中小规模并发(数百连接),且代码编写符合同步思维,迁移成本低。

多进程为何在 IO 场景最不推荐

多进程的进程间通信(Queue、Pipe)依赖序列化(pickle),IO 操作本身已是瓶颈,叠加序列化成本和内存拷贝,反而拖慢整体吞吐。每个进程拥有独立内存空间和解释器,创建和切换需加载完整上下文(页表、文件描述符等),资源占用大(MB 级)。在 IO 密集型场景中,CPU 并非瓶颈,多进程无法带来并行收益,却因高额通信开销而劣于协程和线程,应避免使用。

选型决策速查表

并发方案 切换耗时 内存占用 最大并发量 适用 IO 场景
协程 ~纳秒级 ~数 KB 数万 ~ 数十万 高并发网络服务、爬虫、网关
多线程 ~微秒级 ~数 MB 数百 ~ 数千 中低并发 Web 应用、脚本工具
多进程 ~微秒级(+IPC开销) ~数十 MB 受 CPU 核数限制(逻辑隔离) 数据安全隔离要求高的 IO 任务