Python的GIL把我坑惨了,原来多线程和多进程的区别这么大
一个让我怀疑人生的性能优化前年接了一个图像批处理项目。每天有上万张商品图片需要做缩放、水印和格式转换。我心想“这还不简单多线程并行处理分分钟搞定。”代码写得行云流水import threading from PIL import Image def process_image(image_path): img Image.open(image_path) img img.resize((800, 800)) # 加水印、转格式... img.save(fprocessed_{image_path}) images get_all_images() # 一万张图 threads [] for path in images: t threading.Thread(targetprocess_image, args(path,)) t.start() threads.append(t) for t in threads: t.join()开了20个线程信心满满地跑起来。结果一看CPU监控——8核的服务器CPU使用率只有25%左右跟单线程跑没啥区别。处理速度也没快多少一万张图还是跑了好几个小时。同事路过看了一眼“你用多线程跑CPU密集型任务不知道GIL吗”我“GIL是什么”那天下午我把GIL、多线程和多进程的区别彻底研究了一遍。今天把这些东西讲清楚希望你下次遇到类似问题别像我一样白忙活。第一步GIL到底是什么GIL的全称是Global Interpreter Lock全局解释器锁。它是CPython解释器就是咱们平时用的那个Python里的一个互斥锁机制。它的作用简单粗暴同一时刻只有一个线程能执行Python字节码。也就是说即使你的电脑有8核16核跑Python多线程程序的时候同一时间只有一个核心在工作其他核心都在旁边看着。听到这儿你可能想骂人了“那Python的多线程不就是个摆设吗”别急事情没那么简单。第二步GIL为什么存在GIL不是Python设计者脑子进水搞出来的东西。恰恰相反它是一个有意为之的设计决策。Python的内存管理用的是引用计数——每个Python对象都有一个计数器记录有多少个地方引用了它。当计数器归零时对象就被回收了。问题来了在多线程环境下如果两个线程同时修改同一个对象的引用计数就会出现竞争条件——计数可能只增加了一次而不是两次导致对象永远无法被回收造成内存泄漏。解决这个问题有两种方案给每个对象加锁——细粒度锁性能好但实现极其复杂容易死锁给整个解释器加一把大锁——简单粗暴但限制了并行Python选择了方案二。GIL就像是一个门卫牢牢掌控着Python字节码的执行权确保同一时刻只有一个线程能进门。在单核CPU时代这个设计完全没问题——反正同一时间本来就只有一个线程能用CPU。但多核普及之后GIL就成了Python多线程的“紧箍咒”。第三步多线程到底有没有用有用但要看场景。GIL只限制Python字节码的执行。当线程执行I/O操作比如网络请求、文件读写、数据库查询时它会主动释放GIL。其他等待的线程就可以趁机获取GIL并执行。这就好比一个食堂只有一个打饭窗口GIL。如果你要做的只是“站在窗口前等饭”I/O等待那多几个人排队也没问题——反正大家都在等谁先谁后差别不大。但如果你要做的是一人霸占窗口做复杂操作CPU计算那其他人就只能干等着。I/O密集型任务网络爬虫、文件读写、数据库操作多线程很有效线程大部分时间在等待外部响应不占用CPU等待时释放GIL其他线程可以运行实测20个网络请求4线程比单线程快约4倍CPU密集型任务图像处理、数值计算、加密解密多线程基本没用线程一直在执行计算不释放GIL多个线程轮流抢一把锁加上切换开销可能比单线程还慢实测计算质数4线程比单线程还慢0.5秒有测试数据显示在4核CPU上跑CPU密集型任务单线程耗时10.2秒4线程耗时10.0秒——几乎没有提升。多出来的线程除了抢锁和切换上下文什么都没干。第四步多进程——绕过GIL的真正并行既然多线程被GIL卡死了那怎么办答案是多进程。每个Python进程都有自己独立的解释器和独立的内存空间。每个进程都有自己的GIL互不干扰。所以在多核CPU上多个进程可以真正做到同时运行——一个进程跑在一个核心上。用多进程改造一下我的图像处理代码from multiprocessing import Pool def process_image(image_path): # 同样的处理逻辑 pass if __name__ __main__: images get_all_images() with Pool(8) as p: # 8核CPU开8个进程 p.map(process_image, images)改完之后CPU使用率直接飙到95%以上处理时间从几个小时缩短到了几十分钟。实测数据更能说明问题在4核CPU上计算100万以内质数单线程3.2秒4线程反而要6.1秒线程切换开销GIL竞争但4进程只用了1.8秒接近4倍加速。另一个测试显示4进程方案在4核CPU上能达到3.66倍的加速比。多进程的好处真正利用多核CPU没有GIL干扰每个进程内存隔离不会相互影响多进程的代价进程创建开销大约100微秒到1毫秒线程只需1-5微秒进程间通信需要序列化pickle比较麻烦内存占用大——100个线程增加约15MB内存100个进程增加约800MB数据共享不如线程方便第五步到底该选哪个一张图说清楚场景推荐方案原因网络爬虫、API调用多线程I/O等待时释放GIL轻量高效文件读写、数据库操作多线程同上图像/视频处理多进程CPU密集型需要真并行数值计算、机器学习多进程充分利用多核加密解密、压缩解压多进程CPU密集型有个真实的案例某图像处理项目用多进程处理1080P视频转码速度从单线程的45分钟缩短到了12分钟。还有个爬虫项目用多线程后日抓取量从10万页提升到了80万页。简单粗暴的判断标准如果代码大部分时间在等等网络、等磁盘、等数据库用多线程如果代码大部分时间在算循环、计算、处理用多进程。第六步还有几个坑坑一别在Windows上瞎用多进程Windows创建进程的开销比Linux大得多而且multiprocessing在Windows上需要用if __name__ __main__保护不然会无限递归创建进程。坑二进程间传数据要序列化多线程共享内存传递数据直接传引用就行。多进程不行——每个进程内存独立传递数据需要pickle序列化。如果数据太大序列化本身就很耗时。坑三不是所有第三方库都释放GIL有些C扩展库比如某些旧版本的加密库在执行时不释放GIL即使在做I/O操作也不放。这就导致多线程在这些库上完全没用。用之前最好确认一下。坑四进程数不是越多越好进程数一般等于CPU核心数就够了。开太多进程上下文切换的开销反而会拖慢速度。顺便说一句GIL快没了Python 3.13已经推出了实验性的自由线程Free-Threading模式可以禁用GIL。PEP 703正式提出了让GIL变成可选项的方案。不过目前还是实验阶段性能差距还有待优化早期版本自由线程比非自由线程慢约40%现在已经降到10%以内了。而且就算GIL最终被移除多线程和多进程的适用场景也不会完全重叠——内存模型、通信方式这些本质区别依然存在。所以理解GIL、多线程和多进程的区别在今天依然很有必要。总结一句话记住区别多线程是“一个人干多个活但一次只能干一个”多进程是“多个人各干各的互不干扰”。用我那个图像处理的例子来总结多线程一个人同时操作8台机器但每次只能操作一台——看起来忙实际上效率没提高多进程8个人各操作一台机器——真正的同时干活效率翻倍现在我写代码但凡涉及到并发第一反应就是先判断“这任务是等还是算”等就用线程算就用进程。想清楚再动手少让CPU闲着。

相关新闻

Auto Paper Pipeline: 让论文研究自动化

Auto Paper Pipeline: 让论文研究自动化

🚀 Auto Paper Pipeline: 让论文研究自动化 引言 作为一名AI研究者,你是否每天都在重复这些工作? 手动搜索ArXiv上的最新论文下载PDF并分类整理阅读论文并理解实验设置复现实验结果整理技术报告 Auto Paper Pipeline 应运而生——一个全自…

2026/7/22 15:42:45阅读更多 →
达仁堂·安宫牛黄丸|老字号中医药品牌包装全案设计

达仁堂·安宫牛黄丸|老字号中医药品牌包装全案设计

一、品牌基础信息品牌名称:达仁堂品牌属性:中华老字号、百年中医药品牌、乐家老铺正统后裔,品牌文脉追溯明代永乐年间,拥有六百年中医行医传承,前身历经民间游医、清代太医院医官体系,是国内极具历史底蕴的…

2026/7/22 15:42:45阅读更多 →
生命涌现的小龙虾技能之【Pet Sneeze / Cough Detection | 宠物打喷嚏/咳嗽检测】简介

生命涌现的小龙虾技能之【Pet Sneeze / Cough Detection | 宠物打喷嚏/咳嗽检测】简介

💨 Pet Sneeze / Cough Detection | 宠物打喷嚏/咳嗽检测 智能分析中枢 图片/视频智能分析 结构化报告 历史报告云端查询 🧭 技能概览 | Overview 模块内容🏷️ 技能名称宠物打喷嚏/咳嗽检测🎯 核心目标通过宠物摄像头实时分析…

2026/7/22 15:42:45阅读更多 →
AXI中的burst有几种?都用在什么场景中

AXI中的burst有几种?都用在什么场景中

AXI中的burst有几种?都用在什么场景中 摘要:在 AXI (Advanced eXtensible Interface) 协议中,Burst 传输是数据传输的基本方式,用于提高传输效率。AXI 定义了三种 Burst 类型:FIXED、INCR 和 WRAP。每种 Burst 类型适用于不同的场景,其行为和地址计算方式也不同。…

2026/7/22 16:42:55阅读更多 →
Pinpix:电脑截图工具的首选

Pinpix:电脑截图工具的首选

一键截长图、自动识别文字,可以把截图直接贴在屏幕上方便对照,贴图标注随心改,一键另存为或者复制到剪贴板,这样一款截图软件你是否需要呢,让我们一起来看看吧! 基本功能 截图、贴图、截图并复制等常用功…

2026/7/22 16:42:55阅读更多 →
GD32F470移植CH395Q实现TCP协议

GD32F470移植CH395Q实现TCP协议

tcp_client配置 第一步:资料下载 以太网协议栈芯片 CH395 - 南京沁恒微电子股份有限公司 第二步:准备工程 (1) 首先准备一个编译无报错、可以正常打印和延时的工程文件,官方例程采用STM32F1芯片,但本文采用GD32F470芯片 (2)将例程代码中的PUB文件夹加入,keil工程…

2026/7/22 16:42:55阅读更多 →
自学嵌入式 day 17- c语言-第11章 结构体与共用体 第12章 位运算

自学嵌入式 day 17- c语言-第11章 结构体与共用体 第12章 位运算

第十一章 结构体与共用体11.1 结构体声明:struct Student //结构名,符合标识符规则,第一个字母大写{int id;char name;float score;};定义:struct Student(结构名) s(变量名);s.id 1;//“ . ”结构体运算符,优先级…

2026/7/22 16:42:55阅读更多 →
计算机毕业设计之自媒体平台设计与实现

计算机毕业设计之自媒体平台设计与实现

本论文主要论述了如何使用JSP技术开发一个自媒体平台设计与实现,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述自媒体平台设计与实现的当前背景以及系统开发的…

2026/7/22 16:42:55阅读更多 →
嵌入式视频开发实战:VPDMA与HD_VENC_D寄存器配置与调试指南

嵌入式视频开发实战:VPDMA与HD_VENC_D寄存器配置与调试指南

1. 项目概述与核心价值 在嵌入式多媒体开发,尤其是基于德州仪器(TI)DaVinci或类似SoC平台进行高清视频应用开发时,工程师迟早会与两个核心硬件模块正面交锋: 视频处理直接内存访问(VPDMA) 和 …

2026/7/22 16:40:54阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 0:53:59阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 0:53:59阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 0:53:59阅读更多 →
中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业做小程序,最常见的矛盾是预算有限,但又不希望功能太单薄;没有技术团队,但又希望后续能自己运营;想快速上线,又担心隐性收费和售后失联。选型时如果只看“低价套餐”或“案例数量”,很容…

2026/7/22 0:01:17阅读更多 →
GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

企业做营销,最怕钱花完了,资产没有留下。 效果广告能带来一段时间的曝光,但预算停止后,流量往往也随之停止。短视频内容可能在几天内冲高,也可能很快沉下去。AI搜索时代,企业需要重新思考一个问题&#xff…

2026/7/22 0:01:17阅读更多 →
Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复 一、你的 Agent 在"再想想"的循环里绕了 12 轮,用户已经关窗口了 Agent 与人最大的区别是:人知道什么时候该停下来给答案,Agent 会一直"想"下去。你给 Agent 接…

2026/7/22 0:01:17阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/21 22:53:50阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/21 18:53:30阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/21 18:53:30阅读更多 →