Skip to content

GIL 与并发模型

GIL 原理、线程 vs 进程 vs 协程选型、绕过 GIL 的方案。

Updated View as Markdown
For humans

GIL 与并发模型

校招考察频度:★ 高频(核心必背·高频生死线) 一句话速记:GIL 是 CPython 内存管理(引用计数)的历史枷锁,单进程同瞬时仅一线程能跑字节码;计算密集走多进程真并行,高并发 IO 选协程单线程多路复用。

GIL 是 Python 并发面试的必考题。主线三步:GIL 是什么、影响什么、怎么绕。

GIL 是什么

GIL(Global Interpreter Lock,全局解释器锁):CPython 解释器同一时刻只允许一个线程执行 Python 字节码。

为什么存在:

  • CPython 的内存管理(引用计数)不是线程安全的
  • 加 GIL 是简单粗暴的解法:整个解释器串行,不用给每个对象加锁
  • 代价:多线程无法利用多核跑 Python 代码

多线程到底快不快

分场景,这是考点核心:

场景多线程效果原因
CPU 密集(计算)不加速,甚至更慢GIL 串行执行,还有切换开销
IO 密集(网络、文件)明显加速阻塞等待时释放 GIL,其他线程执行

IO 操作(读写 socket、文件、sleep)会释放 GIL,所以 IO 密集任务多线程有效。CPU 密集任务多线程反而因锁竞争和切换变慢。

三模型选型

并发三模型各管一段

维度线程进程协程
调度操作系统抢占式操作系统事件循环协作式
并行受 GIL 限制真并行(多核)单线程内并发
适用IO 密集CPU 密集高并发 IO
开销中大(内存隔离)小
通信共享内存(要锁)IPC/队列同线程共享

选型一句话:IO 密集用协程或线程,CPU 密集用多进程。高并发网络服务(Web/爬虫)默认协程;计算密集(数据处理)用 multiprocessing 或 Pool。

绕过 GIL 的路径

  • 多进程:每个进程独立解释器、独立 GIL,多核真并行
  • C 扩展:在 C 层释放 GIL(Py_BEGIN_ALLOW_THREADS),如 numpy 的部分操作
  • 其他实现:PyPy 也有 GIL;Jython/IronPython 没有但已边缘化
  • 3.13 实验特性:free-threaded build(无 GIL 构建),仍在演进,生产慎用

工程结论:别指望 Python 多线程跑满多核。CPU 密集任务上多进程或把重计算下沉到 C 库(numpy/pandas 底层已释放 GIL)。

面试追问

  1. GIL 为什么存在? 引用计数线程安全问题的简单解法:解释器全局加锁。牺牲多核并行换实现简单
  2. 多线程什么时候有用? IO 密集:阻塞等待释放 GIL,其他线程趁机执行。CPU 密集无效甚至更慢
  3. 线程、进程、协程怎么选? IO 密集协程/线程,CPU 密集多进程。高并发网络服务用协程
  4. 怎么绕过 GIL? 多进程、C 扩展释放 GIL、3.13 free-threading 实验特性
  5. GIL 会移除吗? 3.13 提供 free-threaded 构建,但默认仍有 GIL。移除影响面太大,渐进演进
Navigation

Type to search…

↑↓ navigate↵ selectEsc close