1. 多线程基础
大家好,我是你们的老朋友。今天咱们聊聊多线程最基础的东西。
说实话,很多同学一上来就撸多线程代码,结果线上崩了都不知道怎么死的。我见过太多这样的案例了。所以第一章,咱们把地基打牢。
1.1 进程与线程:到底差在哪?
先问个问题:你打开一个浏览器,又打开一个,这叫啥?这叫两个进程。
那你在浏览器里开了10个标签页呢?这10个标签页,通常就是10个线程(当然现代浏览器更复杂,但先这么理解)。
说白了,进程是资源分配的最小单位,线程是CPU调度的最小单位。我习惯这么记:进程是房子,线程是房子里干活的人。
核心区别一览:
| 对比项 | 进程 | 线程 |
|---|---|---|
| 资源开销 | 大(独立内存空间) | 小(共享内存) |
| 切换成本 | 高(需要切换页表) | 低(只需切换寄存器) |
| 通信方式 | IPC(管道、消息队列等) | 直接读写共享变量 |
| 健壮性 | 一个崩了不影响其他 | 一个崩了全组陪葬 |
我在项目中遇到过这么个事:有个同事用多进程做爬虫,每个进程开一个浏览器实例。结果跑了半小时,内存爆了。为啥?每个进程都独立加载了完整的Chromium引擎,8G内存根本扛不住。后来改成多线程+单浏览器实例,内存直接降了70%。
我的建议:CPU密集型任务用多进程,IO密集型任务用多线程。别搞反了,否则你会哭的。
1.2 Python的GIL锁:一个让人又爱又恨的东西
聊Python多线程,绕不开GIL。GIL全称Global Interpreter Lock,全局解释器锁。
它的存在,让Python多线程在CPU密集型任务上成了笑话。为什么?因为同一时刻,只有一个线程能执行Python字节码。
你想想看,你开了8个线程,结果它们排队抢一把锁。8个线程跑出来的效果,可能还不如单线程。我刚开始学Python时也踩过这个坑,写了个多线程计算器,结果比单线程还慢,气得我差点砸键盘。
注意:GIL只影响CPU密集型任务。对于IO密集型任务(比如网络请求、文件读写),线程在等待IO时会主动释放GIL,这时候多线程依然有效。
那怎么绕过GIL?我常用的三种方式:
- 用多进程:每个进程有自己的GIL,互不干扰。适合CPU密集型。
- 用C扩展:比如numpy、pandas,它们在C层面释放了GIL。
- 用异步IO:asyncio,单线程搞定高并发。
来看个代码示例,感受一下GIL的威力:
import threading
import time
def count_down(n):
while n > 0:
n -= 1
# 单线程
start = time.time()
count_down(100000000)
print(f"单线程耗时: {time.time() - start:.2f}s")
# 多线程
start = time.time()
t1 = threading.Thread(target=count_down, args=(50000000,))
t2 = threading.Thread(target=count_down, args=(50000000,))
t1.start()
t2.start()
t1.join()
t2.join()
print(f"多线程耗时: {time.time() - start:.2f}s")
跑一下你会发现,多线程版本反而更慢。这就是GIL的“功劳”。
避坑指南:我曾经在数据处理项目里用了多线程,结果跑了3天没出结果。后来换成多进程,6小时搞定。记住:计算密集,别用Python多线程。
1.3 多线程适用场景:什么时候该用?
搞清楚了GIL,咱们聊聊到底什么时候该用多线程。
我个人习惯把任务分成三类:
- IO密集型:网络请求、数据库读写、文件操作。这类任务,线程大部分时间在等IO,GIL基本不构成瓶颈。多线程效果显著。
- CPU密集型:数学计算、图像处理、数据压缩。这类任务,线程一直在抢CPU,GIL就是瓶颈。建议用多进程或C扩展。
- 混合型:既有计算又有IO。比如爬虫,先请求(IO),再解析(CPU)。这种场景,多线程+多进程组合拳最香。
举个例子,我做过一个日志分析系统:
- 读取日志文件(IO密集型)→ 用多线程
- 解析日志格式(CPU密集型)→ 用多进程
- 写入数据库(IO密集型)→ 用多线程
这样搭配,吞吐量提升了8倍。
一句话总结:多线程不是万能药,用对了是神器,用错了是毒药。搞清楚你的任务类型,再决定用不用。
1.4 本章知识体系
下面这张图,是我自己画的,帮你理清本章的核心逻辑:
嗯,这张图把本章三个核心知识点串起来了。你多看几遍,心里就有谱了。
我的经验:刚开始学多线程,别急着写代码。先把进程、线程、GIL这三者的关系理清楚。我见过太多人,连GIL是啥都不知道就开始写多线程,结果线上出bug了才回来补课。磨刀不误砍柴工,基础打牢了,后面才走得稳。
好了,第一章就到这里。记住:多线程不是银弹,但用好了绝对是利器。
可可精品资料库