Appearance
Python 并发工具地图:线程、协程、进程、队列怎么选
对应视频:EP03《Python 并发工具地图》
视频入口:B站 EP03 定时稿(计划公开:2026-08-10 19:42)。 对应合集:Python 并发实战:从基础模型到语音工程。 本文为视频的工程展开版,补充代码模板、排查链路、状态字段和检查清单。 最后核验:2026/08/09 08:26:33
视频把主要工具放到同一张地图上。文章补充选型矩阵和边界条件,后面每一集都会回到这张表。
这张图不是工具排行榜,而是从资源瓶颈到 Python 工具的映射:等待、计算、配额、阶段协作要分别处理。
工具矩阵
| 工具 | 主要解决 | 关键风险 |
|---|---|---|
threading | 手动管理少量线程 | 生命周期、共享状态、异常收集 |
ThreadPoolExecutor | 等待型阻塞任务 | 无限提交、共享状态、CPU 密集误用 |
asyncio | 大量非阻塞 I/O | 伪异步、取消和异常传播复杂 |
ProcessPoolExecutor | CPU 密集任务 | 序列化、启动成本、内存放大 |
queue.Queue | 线程间生产者-消费者 | 停止信号、队列堆积 |
asyncio.Queue | 协程间流水线 | 背压、取消清理 |
| 外部命令池 | ffmpeg、压缩、系统工具 | 退出码、临时文件、并发数 |
选型路径
text
等待网络/API → asyncio 或线程池
等待磁盘 → 有界线程池或分批同步处理
CPU 密集 → 进程池 / 原生库 / 外部命令
GPU 推理 → 有界队列 + batch
多阶段任务 → 队列 + 流水线
需要恢复 → checkpoint + 幂等写入决策表
| 任务 | 首选方向 | 原因 |
|---|---|---|
| 批量下载 URL | asyncio 或线程池 | 大量时间在等网络 |
| 批量读取小文件 | 有界线程池 | 文件 I/O 等待明显 |
| 批量音频转码 | 外部命令池或进程池 | CPU/外部命令为主 |
| 调用 ASR API | asyncio + 限流 | 网络等待和服务端配额 |
| 本地模型推理 | 有界队列 + batch | GPU/显存需要调度 |
| 实时语音 | 线程 + 协程 + 队列 | 采集、网络、回写并存 |
工程补充:怎么把这篇用到项目里
读图方式
ThreadPoolExecutor适合把阻塞等待叠起来,但要限制提交量和收敛异常。asyncio适合高并发网络等待,但前提是调用链真的非阻塞。ProcessPoolExecutor适合 CPU 密集大任务,队列和外部命令池适合多阶段工程流程。
排查路径
- 先用顺序版本确认正确性,再对不同工具跑小规模对比,不要从生产规模直接试。
- 线程池实验看吞吐、连接数、错误率;异步实验看 in-flight、timeout、取消;进程池实验看序列化和 RSS。
- 工具选型完成后必须再加控制层:并发上限、超时、重试、状态表和压测。
问题、证据和解决动作
| 问题现场 | 先查什么 | 解决动作 |
|---|---|---|
| 阻塞 SDK 不能换成异步库 | 调用栈、响应耗时、CPU 低 | ThreadPoolExecutor 或 asyncio.to_thread |
| HTTP 客户端支持 async | 连接池、QPS、timeout | asyncio + Semaphore + timeout |
| 纯 Python 计算占满 CPU | py-spy、cProfile、CPU util | 进程池或原生扩展 |
| 任务有扫描、转码、识别、落盘 | 阶段耗时、qsize、失败状态 | 生产者-消费者流水线 |
落地边界
- 工具越强,工程约束越不能少;没有边界的并发工具就是更快的失控入口。
- 不要混用太多模型解决同一个阶段,复杂度通常会超过收益。
常见失败模式
| 错误写法 | 现象 | 修正 |
|---|---|---|
| 一个线程池处理所有阶段 | 快阶段堆积,慢阶段拖垮全局 | 按阶段拆池,用队列连接 |
| 所有网络任务都用线程 | 线程很多,内存和调度成本上升 | 支持异步库时考虑 asyncio |
| 所有 CPU 任务都用进程池 | 小任务反而变慢 | 增大任务粒度,测序列化成本 |
| 队列无上限 | 内存不断上涨 | 使用有界队列和背压 |
实战检查清单
- 当前库是否支持异步。
- 当前任务是否需要共享状态。
- 当前任务参数和结果是否容易序列化。
- 当前任务是否有外部配额。
- 当前任务是否需要失败后恢复。
- 当前任务是否有多个瓶颈不同的阶段。
读完之后能完成什么
- 能为常见任务给出并发工具初判。
- 能说出每种工具的主要边界。
- 能理解后续线程池、asyncio、进程池章节的学习位置。
