Python 并发模型总览

分清并发与并行、I/O 密集与 CPU 密集;在线程、进程与 asyncio 之间做负载匹配选型。

#type / concept #status / growing #tech / dev #resource / python #tech / lang / python

[!info] 关联笔记

Python 并发模型总览

这个概念为什么出现

“慢”有不同原因:等网络,或算矩阵。用错模型会:

  • 在 GIL 下徒增线程却不加速 CPU
  • 用 asyncio 包一层仍调用阻塞 SDK
  • 用多进程处理简单 I/O 却付出序列化成本

[!abstract] 一句话理解 先判断瓶颈是 I/O 还是 CPU,再在线程/进程/asyncio 中选择;并发结构解决重叠等待,并行结构解决多核计算。

最小可运行示例

先把示例放进业务场景,再看代码:

场景:运维脚本给三类任务贴标签选型

# concurrency_choose.py
# 业务意图:根据任务画像输出推荐模型(教学用规则)。
# 教学点:
# - I/O vs CPU;
# - 模型不是银弹;
# - 决策先分类。

def recommend(kind: str) -> str:
    table = {
        "many_http": "asyncio or thread pool",
        "blocking_sdk": "thread pool / to_thread",
        "cpu_hash": "process pool / native ext",
        "simple_script": "sync first",
    }
    return table[kind]


def main() -> None:
    for k in ["many_http", "blocking_sdk", "cpu_hash", "simple_script"]:
        print(f"{k} -> {recommend(k)}")


if __name__ == "__main__":
    main()

建议运行:

python concurrency_choose.py

期望输出:

many_http -> asyncio or thread pool
blocking_sdk -> thread pool / to_thread
cpu_hash -> process pool / native ext
simple_script -> sync first

结合场景再看三个关注点

  1. 先测量再并发——同步正确实现优先。
  2. 阻塞 SDK 不会因为函数写成 async 就变非阻塞。
  3. CPU 看多进程或下沉扩展。

核心概念与准确模型

模型擅长成本
多线程阻塞 I/O 并发GIL 限 CPU;共享内存要同步
多进程CPU 并行内存/序列化/启动
asyncio高并发 I/O生态需异步化;禁阻塞
同步简单正确吞吐上限

边界情况与反直觉行为

  1. 混合负载需要分阶段/分池
  2. GIL 在 I/O 或部分 C 扩展中会释放。
  3. 容器 CPU 限额改变“多进程收益”。

常见误区

[!warning] 常见误区:并发 = 多线程 错误理解:只有一种手段。
正确模型:多模型并存,按负载选型。

工程实践

  • 统一超时、取消、背压
  • 线程/进程池设上限
  • 观测队列长度与延迟

本节总结

选型图比 API 背诵重要。后续三篇分别深入线程/GIL、进程与 asyncio 细节。

自测题

  1. 为何 CPU 密集不优先 asyncio?
  2. 阻塞 SDK 在异步服务中怎么放?
参考答案
  1. 事件循环通常单线程,算满会卡住所有任务。
  2. 丢到线程池/to_thread,或换异步库。

延伸阅读与资料来源

资料类型支撑内容
concurrent.futures文档线程/进程池
asyncio文档异步
创建于 2026/7/15 更新于 2026/7/15