首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python 的多线程就是个摆设?不,原来是你没选对IO场景,这差距大到离谱

Python 的多线程就是个摆设?不,原来是你没选对IO场景,这差距大到离谱

原创
作者头像
风一样的男子
发布2026-07-24 13:58:42
发布2026-07-24 13:58:42
520
举报
文章被收录于专栏:编程教程编程教程

一个加班的夜晚

凌晨两点,办公室只剩你一个人。

屏幕上是一段爬虫代码,你要抓取一万个网页的数据。单线程跑了一个小时,才完成不到三分之一。你心想:Python不是支持多线程吗?开几个线程一起跑,速度不就翻倍了?

于是你花十分钟改成了多线程版本,信心满满地运行——

结果傻眼了:速度几乎没变。甚至,CPU占用率倒是上去了,但进度条还是慢得像蜗牛爬。

你开始怀疑人生:Python的多线程,是不是就是个摆设?

别急。你不是一个人遇到这个问题。无数Python开发者都在这条路上踩过坑——包括我自己。

今天咱们就掰开揉碎聊清楚:Python的多线程到底有没有用,什么时候有用,什么时候不仅没用反而更慢。

先讲个故事:GIL是个什么玩意儿

要理解多线程为什么有时候不灵,得先认识一个东西——GIL,全称叫全局解释器锁(Global Interpreter Lock)。

它是CPython(就是咱们平时用的那个Python解释器)里的一个机制。简单说就是:同一时刻,只有一个线程能执行Python的字节码

什么意思呢?打个比方——

你开了一家奶茶店,店里只有一个操作台(这就是GIL)。你雇了10个员工(线程),但不管多少人,同一时间只能有一个人在操作台前面做奶茶。其他人要么在等,要么在干别的不需要操作台的活儿(比如招呼客人、打包)。

所以,就算你的电脑有8个CPU核心,跑Python多线程程序时,真正干Python代码活的,永远只有一个核心

那问题来了:既然只能有一个线程执行代码,多线程还有什么意义?

答案是:看场景。

场景一:CPU密集型任务——开再多线程也没用

什么叫CPU密集型?就是那种大量消耗CPU计算资源的活儿,比如:

  • 计算圆周率小数点后一亿位
  • 训练一个机器学习模型
  • 处理海量数据的排序和统计
  • 图片滤镜处理

这些任务的特点是:CPU一直在吭哧吭哧算,基本不休息。

咱们做个实验。假设要计算1到100万之间的质数个数:

单线程跑完需要 28.63秒

改成4个线程一起跑,你猜多久?

29.15秒

不仅没快,反而慢了0.52秒

为什么会这样?因为4个线程在抢同一个操作台(GIL) 。每个线程干一会儿就得让位给下一个,换来换去还要花时间(这叫上下文切换开销)。结果就是:并行没实现,开销倒增加了

有开发者做过一个更直观的测试:单线程执行1亿次减操作耗时约6.5秒,两个线程各执行5千万次时,总耗时反而增加到6.8秒。多线程比单线程还慢——这跟直觉完全相反。

所以结论很扎心:对于纯计算型任务,Python的多线程确实是个摆设

那CPU密集型任务想加速怎么办?用多进程multiprocessing)。每个进程有自己的GIL,可以跑在不同的CPU核心上,真正实现并行。同样是上面的质数计算,4进程只需要 7.82秒,接近4倍提速。

场景二:IO密集型任务——多线程的神仙时刻

再来看另一种任务:IO密集型

IO就是输入输出(Input/Output),包括:

  • 网络请求(爬虫、调用API)
  • 读写文件
  • 数据库查询

这类任务的特点是:大部分时间在等

你发一个网络请求,数据从服务器传回来需要几百毫秒。这段时间CPU是闲着的,啥也没干,就在那儿干等。

这时候多线程就派上用场了。

还是做实验。模拟20个网络请求,每个请求等1秒左右:

单线程顺序执行:5.12秒

4个线程并发执行:1.28秒

提速接近4倍

为什么会这样?还记得GIL吗——那个只有一个操作台的奶茶店。

当一个线程发起网络请求后,它就在那儿等服务器回复。这时候它不需要操作台了。GIL就会自动释放,让其他线程上去用操作台。

等数据回来了,这个线程再重新获取GIL,继续处理结果。

换句话说:线程在等待IO的时候不占用GIL,其他线程可以趁机执行。这就实现了“伪并行”——虽然同一时刻只有一个线程在执行Python代码,但多个线程可以交替工作,把等待时间充分利用起来。

有开发者测试过网络请求场景,多线程的执行速度大约是单线程的2倍。另一个测试中,线程数增加到5倍时,速度提升约3.8倍,接近线性增长。

所以结论是:对于网络请求、文件读写这类IO密集型任务,Python的多线程非常有用

那多进程呢?IO场景下反而更慢

你可能会想:既然多进程能绕过GIL,那IO密集型任务也用多进程不更好?

事实恰恰相反。

同样是上面那个20个网络请求的实验:

  • 4线程:1.28秒
  • 4进程:1.35秒

多进程反而更慢一点

原因是:创建进程的开销远大于创建线程。进程有自己独立的内存空间,创建和销毁都要花更多资源。对于IO密集型任务,线程已经能很好地利用等待时间了,没必要用更重的进程。

一张图总结

任务类型

多线程

多进程

推荐方案

CPU密集型(计算、运算)

❌ 更慢

✅ 接近线性提速

多进程

IO密集型(网络、文件、DB)

✅ 大幅提速

⚠️ 略慢于多线程

多线程

实际工作中怎么选?

判断标准很简单:看你的程序是把时间花在“算”上,还是花在“等”上

  • 如果你的程序CPU一直100%满负荷运转——用多进程
  • 如果你的程序大部分时间在等网络响应、等磁盘读写——用多线程

很多实际项目是混合型的。比如一个爬虫程序:

  • 下载网页:IO密集型 → 用多线程
  • 解析HTML:CPU密集型 → 用多进程

这时候可以把两者结合起来:用多进程池处理解析,用多线程池处理下载。

顺便提一句:Python 3.13的新变化

从Python 3.13开始,官方支持了一个叫自由线程(free-threading) 的构建模式,可以禁用GIL

在这个模式下,多线程终于可以在CPU密集型任务上实现真正的并行。有测试显示,在M4 MacBook Air上实现了2.83倍的提速。

不过注意:目前这还是个实验性功能,默认并没有启用。在生产环境中,大部分项目用的还是带GIL的常规Python。所以理解GIL的规则、知道什么时候该用多线程什么时候该用多进程——依然是每个Python开发者的必修课

回到开头那个故事

凌晨两点,你写的爬虫慢得像蜗牛。

现在你知道了:问题不在于“Python的多线程没用”,而在于你没搞清楚自己的任务类型。

如果你爬虫的瓶颈是网络请求的等待时间——开多线程,速度立竿见影。

如果你爬虫的瓶颈是解析网页的CPU计算——开再多线程也没用,改用多进程。

同样是多线程,用对场景是神器,用错场景是摆设。

这差距,真的离谱。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一个加班的夜晚
  • 先讲个故事:GIL是个什么玩意儿
  • 场景一:CPU密集型任务——开再多线程也没用
  • 场景二:IO密集型任务——多线程的神仙时刻
  • 那多进程呢?IO场景下反而更慢
  • 一张图总结
  • 实际工作中怎么选?
  • 顺便提一句:Python 3.13的新变化
  • 回到开头那个故事
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档