Python 的 全局解释器锁(Global Interpreter Lock,简称 GIL)

Python 的 全局解释器锁(Global Interpreter Lock,简称 GIL) 是 CPython 解释器(Python 官方实现)里的一个核心机制,用一句话讲:

🔒 GIL 是一个互斥锁,用来保证任意时刻只有一个线程在执行 Python 字节码。

它是 Python 单线程安全的基础,但也是 Python 多线程性能瓶颈的根源。

一、为什么会有 GIL?

要理解 GIL 的由来,要先看 CPython 的底层:
• CPython 是用 C 语言 实现的;
• Python 对象的内存管理依赖 引用计数机制(Reference Counting);
• 每个对象都有一个 ob_refcnt 计数,表示有多少个地方引用了它;
• 当 ob_refcnt 变为 0 时,对象就会被释放。

问题来了👇
如果多个线程同时操作同一个对象,比如:

x = []

线程 A:x.append(1)

线程 B:x.append(2)

这时两个线程会同时修改 x 的引用计数。
如果不加锁,ob_refcnt 可能被改乱(竞态条件 race condition),导致内存崩溃。

为了避免这种“多线程修改内存结构”出错,CPython 设计者在最初就引入了 GIL,让任意时刻只有一个线程能执行 Python 解释器层面的操作,从而保证对象引用计数的线程安全。

✅ 简单说:GIL 是为了解决多线程下的内存安全问题,而不是为了性能。

二、GIL 的工作方式

可以想象 Python 解释器的执行过程像这样:
1. Python 启动时创建一个全局锁(_PyRuntime.ceval.gil)。
2. 任意线程在执行 Python 字节码前,必须先“拿到 GIL”。
3. 当该线程执行一段时间(或执行完一定数量的字节码)后,会释放 GIL。
4. 其他线程才能获得 GIL 继续执行。

伪代码示意:

while True:
acquire(GIL)
execute_some_bytecode()
release(GIL)
switch_thread()

这意味着:
• 所有线程会轮流获得执行权;
• 在任意时刻,只有一个线程在执行 Python 代码。

三、GIL 导致的性能问题

因为 GIL 的存在:

1️⃣ 多线程无法并行执行 CPU 计算

import threading

def cpu_task():
for _ in range(10**7):
pass # 纯计算

threads = [threading.Thread(target=cpu_task) for _ in range(4)]
for t in threads: t.start()
for t in threads: t.join()

你以为 4 个线程能加速执行,结果:
• 实际上它们串行地轮流运行;
• 4 核 CPU 只用到一个核;
• 运行时间 ≈ 单线程 × 线程数。

2️⃣ 多线程依然有上下文切换开销
• Python 解释器会定期释放 GIL(默认每 5ms 左右),让别的线程有机会执行;
• 但这种切换带来 线程调度、锁竞争 等开销。

结果是:

多线程不但没加速,还可能更慢。

四、GIL 什么时候无害甚至有益?

GIL 的坏处主要在 CPU 密集型场景。
但在 I/O 密集型任务(网络请求、文件、数据库)中,反而没那么严重:

import threading, time, requests

def io_task():
requests.get(“https://example.com”)

threads = [threading.Thread(target=io_task) for _ in range(20)]
for t in threads: t.start()
for t in threads: t.join()

•	网络 I/O 时,线程会释放 GIL;
•	其他线程可趁机执行;
•	实际上能达到“伪并行”的效果;
•	所以多线程在 I/O 场景仍然有效。

✅ 因此:

场景 是否受 GIL 影响 推荐方案
CPU 密集(加密、推理、压缩) 严重影响 多进程 multiprocessing
I/O 密集(网络、文件) 影响较小 多线程或 asyncio

五、如何绕过 GIL 限制?
1. 多进程(multiprocessing)
• 每个进程都有自己的 Python 解释器和 GIL;
• 真正的并行;
• 适合 CPU 密集任务。

from multiprocessing import Pool
with Pool(4) as p:
p.map(cpu_task, range(4))

2.	C 扩展释放 GIL
•	NumPy、Pandas、TensorFlow 等底层用 C/C++ 实现;
•	在执行底层计算时会手动释放 GIL;
•	因此 NumPy 的矩阵运算能并行跑。
3.	使用无 GIL 的解释器
•	例如:
•	Jython(运行在 JVM 上,没有 GIL,但慢)
•	IronPython(运行在 .NET 上)
•	PyPy STM(早期实验性支持多线程)
•	Python 3.13+:官方开始实验性引入 “No-GIL 模式”!

六、Python 3.13 的“无 GIL”进展

Python 3.13 引入了可选的 “Free Threading” 模式:

./configure --disable-gil
make

这意味着未来的 Python 版本可能:
• 去掉 GIL;
• 改为细粒度锁;
• 让真正的多线程并行成为可能。

不过目前(截至 2025 年)仍在实验阶段,很多第三方库还不兼容。

七、总结对比

特性 有 GIL(当前 CPython) 无 GIL(未来方向)
多线程并行 ❌ 否(只能伪并行) ✅ 是(多核并行)
内存安全 ✅ 简单 ⚠️ 需细粒度锁
性能(单线程) ✅ 快 ⚠️ 略有损耗
兼容性 ✅ 完全兼容 ⚠️ 需改动 C 扩展
实现复杂度 ✅ 低 🚧 高

🧠 一句话总结

GIL 是 Python 的“全局安全锁”——保证线程安全,却牺牲了多核并行。

•	对 IO 任务影响不大;
•	对 CPU 密集型任务致命;
•	可用多进程或 C 扩展绕过;
•	Python 3.13 以后,有望逐步告别它。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MonkeyKing.sun

对你有帮助的话,可以打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值