GIL全局解释性锁的原理及影响

GIL,全称 Global Interpreter Lock,是 CPython 解释器里的一个全局互斥锁。它的核心作用是:

保证同一时刻只有一个线程在执行 Python 字节码。

> 注意限定词:主要说的是 CPython,也就是最常用的 Python 实现。不是所有 Python 实现都有同样的 GIL。

 

为什么需要 GIL

CPython 的很多内部对象不是线程安全的,尤其是引用计数。

比如:

a = []
b = a

CPython 会给对象维护引用计数。多个线程如果同时修改同一个对象的引用计数,就可能出现竞态:

线程 A: refcount += 1
线程 B: refcount -= 1

如果没有同步保护,引用计数可能错,轻则内存泄漏,重则对象被提前释放导致崩溃。

GIL 的做法很粗暴但有效:执行 Python 字节码前先拿全局锁。这样 CPython 内部大量对象操作就不需要每个地方都单独加细粒度锁,解释器实现更简单,单线程性能也更好。

 

GIL 保护的是什么

它主要保护的是 CPython 解释器内部状态,例如:

  • Python 对象引用计数
  • 对象内存管理
  • dict/list/tuple 等核心对象的内部结构一致性
  • 当前线程状态、frame、异常状态等解释器运行时结构
  • C extension 调用 Python C API 时的安全性

它带来的直接后果

CPU 密集型 Python 线程不能真正并行执行 Python 字节码。

虽然GIL限制了线程并发只有1个,但 I/O 多线程仍然有用

因为线程在做阻塞 I/O 时通常会释放 GIL,例如:

  • 读写文件
  • 网络请求
  • socket 等待
  • sleep
  • 一些数据库请求

所以这种场景多线程仍然有效:

# 多个线程同时等网络响应
requests.get(...)

线程 A 等网络时释放 GIL,线程 B 可以继续执行 Python 代码。

 

一句话总结

GIL 是 CPython 为了保护解释器内部对象和内存管理而引入的全局锁。它让解释器实现简单、安全,但代价是:同一个 Python 进程内,多个线程不能并行执行 Python 字节码。I/O、C 扩展、CUDA 计算可以通过释放 GIL 绕开这个限制。

posted @ 2026-08-05 16:51  战拖者  阅读(3)  评论(0)    收藏  举报