提示:本网站现在为维护调试状态

Python 并发:asyncio vs ThreadPool vs ProcessPool

Choyeon
Choyeon
2026年9月5日 1 分钟阅读 664 阅读
508 字 1,785 字符 更新于 2026年11月8日
Python 并发:asyncio vs ThreadPool vs ProcessPool
目录

由于全局解释器锁(GIL)的存在,Python 并发性选择常让人困惑。IO 密集和 CPU 密集场景需要完全不同的模型,选错会让性能不升反降。

三大模型原理与代码

线程池提交阻塞函数到系统线程,GIL 在 IO 等待时释放,并发 10-50;进程池子进程彻底绕 GIL,适合 CPU 任务但传参有序列化开销;asyncio 单线程调度协程,适合超大量轻量 IO。

import asyncio, time, requests, httpx
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, as_completed
from typing import List

URLS = [f"https://jsonplaceholder.typicode.com/posts/{i}" for i in range(1, 51)]

def fetch_sync(url: str) -> dict:
    return requests.get(url, timeout=10).json()

async def fetch_async(client, url: str) -> dict:
    r = await client.get(url, timeout=10.0)
    return r.json()

def run_threadpool(urls, maxw=20):
    t0 = time.perf_counter()
    with ThreadPoolExecutor(max_workers=maxw) as ex:
        fs = [ex.submit(fetch_sync, u) for u in urls]
        results = [f.result() for f in as_completed(fs)]
    print(f"[ThreadPool] {len(results)} tasks, {time.perf_counter()-t0:.2f}s")

def cpu_heavy(n):
    sieve = [True]*(n+1); sieve[0]=sieve[1]=False
    for i in range(2, int(n**0.5)+1):
        if sieve[i]: sieve[i*i::i] = [False]*len(sieve[i*i::i])
    return sum(sieve)

def run_processpool(args):
    t0 = time.perf_counter()
    with ProcessPoolExecutor() as ex:
        results = list(ex.map(cpu_heavy, args))
    print(f"[ProcessPool] sum={sum(results)}, {time.perf_counter()-t0:.2f}s")

async def run_asyncio(urls):
    t0 = time.perf_counter()
    async with httpx.AsyncClient() as client:
        tasks = [fetch_async(client, u) for u in urls]
        results = await asyncio.gather(*tasks)
    print(f"[asyncio] {len(results)} tasks, {time.perf_counter()-t0:.2f}s")

if __name__ == "__main__":
    run_threadpool(URLS)
    run_processpool([100000]*8)
    asyncio.run(run_asyncio(URLS))

选型决策与性能对比

纯 CPU 运算 → ProcessPool;网络/文件 IO → asyncio 或 ThreadPool;混合场景 → asyncio.run_in_executor 把 CPU 任务扔进程池,IO 走协程。

对比维度 ThreadPool ProcessPool asyncio
原理 多线程共享GIL 多进程独立GIL 单线程事件循环+协程
GIL影响 IO时释放/CPU无效 完全无 单线程无竞争
50HTTP请求 ~5-8s ~40s(启动慢) ~1.5-3s
8个CPU素数 ~45s(串行) ~7s(多核) ~40s(单线程)
最大并发规模 数百 CPU核心×2 数千~数万
改造成本 低 中(可pickle) 高(全链路async)

最佳实践

IO 优先 asyncio,第三方库全同步才退用 ThreadPool。CPU 直接多进程,进程数不超过核心数 1-2 倍。

X微博Telegram

本文作者

投票

你最希望 Rosetta 优先加入哪项功能?

社区投票(演示数据,可后台删除)

评论 (7)

0 / 3000
技术笔记控
技术笔记控tech-notes.fun2026年9月3日

受益匪浅,感谢大佬分享!

摸鱼达人小王
摸鱼达人小王2026年9月2日

请问一下,文中提到的连接池配置,如果是在高并发场景下,一般设置多少比较合适?

嵌入式极客
嵌入式极客embedded-lab.io2026年9月2日

代码示例里那个 SQL 查询是不是应该加个 LIMIT?不然数据量大的时候全表扫描会很慢哦。

产品汪本汪
产品汪本汪pmdiary.io2026年9月2日

有个小问题:你文中用的是 @Async 注解,这个默认用的是 SimpleAsyncTaskExecutor,生产环境是不是最好手动配一个线程池?

游戏策划阿哲
游戏策划阿哲2026年9月1日

楼主,我按照你的步骤操作后启动报错:Error creating bean with name 'dataSource',版本是 Spring Boot 3.2,请问有遇到过吗?

奶茶味程序媛
奶茶味程序媛2026年9月1日

建议加一下关于幂等性的讨论,现在的分布式系统里这个真的太重要了,很多坑都是没处理好幂等导致的。

DevOps小能手
DevOps小能手devops-lab.cn2026年9月1日

作为一个刚入行的后端新人,这篇文章帮我理清了好多概念,谢谢博主持续输出高质量内容!

相关文章

算法与数据结构:动态规划 5 大解题模板

算法与数据结构:动态规划 5 大解题模板

彻底掌握动态规划:先给出通用 DP 解题五步法,再精解五大高频模板:背包类、子序列类、区间DP、状态压缩DP、树形DP,每个模板附典型代码与变形要点。

1 分钟阅读
快速上手 FastAPI - 构建高性能 REST API

快速上手 FastAPI - 构建高性能 REST API

FastAPI 是现代 Python Web 框架中的佼佼者,基于类型提示自动生成文档、支持异步操作、性能媲美 Node.js。本文将通过实战项目带你从零构建一个完整的 CRUD API,涵盖路由定义、请求验证、依赖注入、数据库集成等核心特性,让你在 30 分钟内掌握 FastAPI 的精髓。

这篇文章需要访问密码 4 分钟阅读
RAG 检索增强生成实战:Embedding + Vector DB + ReRank

RAG 检索增强生成实战:Embedding + Vector DB + ReRank

从零搭建生产级 RAG 系统:文档分块策略(Chunk Size/重叠窗口)、Embedding 模型选型与向量化、向量数据库(PGVector/Milvus)检索过滤、Reranker 重排精修 Top-K,加上引用溯源和 Prompt 压缩优化,附完整可运行代码。

1 分钟阅读
Alembic 深度指南:数据库迁移 + 自动生成 + 分支合并

Alembic 深度指南:数据库迁移 + 自动生成 + 分支合并

SQLAlchemy 官方迁移工具 Alembic 完全指南:从 env.py 配置、autogenerate 自动检测模型变更(字段、索引、约束)、批处理脚本、downgrade 回滚策略,到多人并发开发时 migration 分支冲突、head 分叉合并的标准操作流程,附生产部署检查表。

1 分钟阅读
Nuxt 3 进阶 - SSR 与 SSG 深度解析

Nuxt 3 进阶 - SSR 与 SSG 深度解析

Nuxt 3 基于 Vue 3 和 Vite 构建,带来了全新的渲染引擎 Nitro。本文深入剖析服务端渲染(SSR)、静态站点生成(SSG)、增量静态再生(ISR)三种核心模式的工作原理、适用场景与性能差异。配合真实代码演示如何配置渲染策略、优化首屏加载时间、处理缓存策略,打造极致用户体验。

1 分钟阅读
Redis 缓存设计模式

Redis 缓存设计模式

系统讲解三种核心缓存模式:Cache-Aside(旁路缓存)一致性保障、Write-Through(写穿透)原子性保证、Write-Behind(写回)高吞吐异步写入,以及缓存击穿/穿透/雪崩解决方案。

1 分钟阅读