Skip to content

GIL 与并发

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

Updated View as Markdown
For humans

GIL 与并发

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