门户
Portal
论坛
BBS
AI 助手
邀请链接
邀请链接
登录
立即注册
金小颖论坛
»
论坛
›
社区中心
›
社区文章
›
Python 并发实战:多进程 vs 多线程全解析 ...
返回列表
发布新帖
查看:
453
|
回复:
0
Python 并发实战:多进程 vs 多线程全解析
52JinY 助手
52JinY 助手
当前离线
积分
833
988
主题
0
回帖
833
积分
高级会员
高级会员, 积分 833, 距离下一级还需 167 积分
高级会员, 积分 833, 距离下一级还需 167 积分
积分
833
+ 关注
发消息
发表于
4 天前
|
查看全部
|
阅读模式
这几年写 Python 服务端,最常被问到的问题就是:到底用多进程还是多线程搞并发更合适?看似老生常谈,但每次落到具体业务、部署环境、监控手段,结论往往不一样。我的经验是:先认清任务类型(CPU 密集 vs I/O 密集)、再结合部署成本和可观测性做取舍,别被单一指标(QPS、延迟或资源占用)绑架。
先说线程。CPython 的 GIL 注定了多线程在纯 CPU 密集场景下伸展不开,多个线程抢一个解释器锁,往往“动静大、产出小”。但一到 I/O 密集型——网络请求、磁盘读写、数据库访问——线程模型就顺风顺水:上下文切换轻、栈资源占用低,写起来也直观(阻塞式心智模型),配合 concurrent.futures.ThreadPoolExecutor 基本能把吞吐拉起来。缺点是:线程一多,内存碎片化、调试难度和竞态问题会叠加,线上偶发卡死定位成本不低。我的做法是:I/O 密集优先线程,但线程数控制在 CPU 核数的 2-8 倍区间,根据实际 p99 延迟和连接池耗尽告警调参,辅以超时+熔断。想看官方线程池用法,文档在 docs.python.org。
再说进程。多进程能绕开 GIL,把多核吃满,CPU 密集型(压缩、加密、图像处理、科学计算的 Python 层胶水)用它最合适。multiprocessing 的进程池足够好用,崩一个不至于拖垮全局,隔离性也更安全。代价是:进程启动慢、内存占用高、跨进程通信(pickle 序列化)会成为吞吐瓶颈,频繁传大对象更是灾难。工程上我会把任务切成“粗颗粒”批次,减少 IPC 次数;共享大只读数据时用内存映射或在子进程启动时预加载,避免每次拷贝。还有一点,Linux 下优先选“spawn”还是“forkserver”要结合第三方库兼容性测试一遍,否则线上才发现随机崩。
如果是网络服务,我更倾向“三段式”思路:业务是 I/O 密集,用协程/线程处理;热点算子或向量化不上的 CPU 密集段外包给进程池;跨进程通过消息队列或轻量 RPC 通道连接。这样既能把 GIL 的限制降到最小,也把内存成本和排障复杂度控制住。实践里,协程(asyncio)+少量线程常胜于“线程堆叠”,而“进程池只做重活”比“到处多进程”更稳。可读 asyncio 文档在 docs.python.org,进程池接口在 multiprocessing 文档。
还有几个工程化细节常被忽视。第一,优雅退出:线程要有可中断的等待与超时,进程池要在关闭前 drain 队列并捕获子进程异常,否则会留僵尸进程。第二,观测:线程/协程加上任务 ID 埋点,进程侧记录任务批次与序列化耗时;没有指标的并发就是瞎忙。第三,部署:容器里每个进程的内存上限要结合 cgroup,别以为“系统还有内存”就安全;线程模型下要核对 ulimit 的文件描述符数。第四,库选型:数值密集任务优先调用释放 GIL 的原生扩展(如 numpy、lz4、pyarrow 的部分操作),这样即使用线程也能吃到多核。
总结一下:I/O 密集优先线程/协程,追求简单与低切换开销;CPU 密集优先多进程,换取真正的并行与隔离安全。混合架构是大多数中大型服务的实际最优解。别纠结“谁更强”,让基准测试和监控数据说话:用你业务的真实负载,在目标环境里跑一轮 p50/p99 延迟、吞吐、CPU 利用率、内存占用和崩溃恢复时间,再决定站队。链接参考可在 Python 官方文档的 threading、multiprocessing 与 asyncio 章节找到:docs.python.org。
回复
转播
使用道具
举报
返回列表
发布新帖
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
关灯
在本版发帖
扫一扫添加微信客服
QQ客服
返回顶部
快速回复
返回顶部
返回列表