GIL 为什么存在?

考查重点:解释器并发保护与性能代价。GIL 简化 CPython 对象与引用计数的并发保护;代价是传统构建中 CPU 密集 Python 线程难以多核并行

本题目录

参考答案

核心回答

GIL 是 CPython 为保护解释器内部共享状态而采用的一把互斥锁,是实现上的取舍,不是 Python 语言规定所有解释器都必须有的机制。

在 CPython 默认启用 GIL 的构建中,同一解释器内的线程,执行 Python 字节码、访问 Python 对象时通常需要持有 GIL,因此这些线程不能同时在多个核上执行这部分代码。

它的主要作用是让对象引用计数、容器内部结构等操作得到协调,简化解释器和 C 扩展访问 Python 对象时的同步约定。代价是限制同一解释器中纯 Python 计算任务的线程并行能力。但线程仍是真正的操作系统线程,多线程并没有消失。

为什么需要这把锁,为什么不直接删掉?

CPython 的传统对象实现依赖许多共享状态。例如两个线程同时增加同一对象的引用计数,如果没有恰当同步,两次增加可能只留下了一次的结果,进而破坏对象生命周期的判断。容器也要维护长度、元素和引用等内部关系。

GIL 用较粗的互斥范围,避免每处访问都独立处理这些竞争,也让 C 扩展可以遵循“持有 GIL 后操作 Python 对象”的约定。这降低了实现复杂度,但没有让并行计算的需求消失。

因此,去掉 GIL 不等于删除一次加锁调用,还必须重新处理引用计数、内存回收、容器同步和扩展兼容性,并评估单线程开销与多线程扩展能力。自由线程 CPython 正是通过调整这些机制来支持没有 GIL 的执行,而不是取消所有同步。

GIL 对实际任务有什么影响?

  • 主要执行 Python 代码的 CPU 密集任务:例如多个线程分别做大量整数运算,通常不能靠增加线程数让同一解释器充分利用多核,还可能增加调度与竞争成本。任务可拆分时,可以考虑多进程,同时承担启动、通信和数据传输成本。
  • 主要等待 I/O 的任务:例如并发等待多个网络响应,常见阻塞 I/O 路径会释放 GIL,让其他线程继续执行,因此多线程仍可能提高吞吐。效果取决于真正的耗时位置和并发上限。
  • 原生扩展中的计算:扩展可以在不访问 Python 对象的计算区间释放 GIL,所以不能把“同一解释器的 Python 字节码受限”扩展成“所有 C 扩展计算都只能使用一个核”。是否释放,要看具体实现。

这些是选型依据,不是固定的性能保证。异步 I/O 也可以组织大量等待任务,但不会自动把 CPU 密集的 Python 代码变成多核并行计算。

有 GIL,业务代码还需要锁吗?

需要。GIL 主要保护解释器内部的相应操作,不保证一整段业务流程原子执行。

例如“检查库存是否足够→扣减库存→记录结果”包含多次操作,线程可能在这些操作之间切换,函数调用中也可能发生 I/O 或释放 GIL。需要按共享状态的业务约束使用锁、队列或其他协调机制,不能因为某次简单计数实验恰好没出错,就认定业务不会竞争。

现在的 CPython 仍然一定有 GIL 吗?

不是。CPython 3.13 引入了实验性的自由线程构建,3.14 起进入正式支持但仍可选的阶段;当前 3.15 文档也区分默认启用 GIL 的构建与自由线程构建。

自由线程构建在关闭 GIL 时,允许多个线程并行执行 Python 代码,但不保证所有程序自动加速。还要确认运行的是哪种构建、运行时是否启用 GIL、依赖的扩展是否支持自由线程;导入未声明支持的扩展时,GIL 可能被重新启用。没有 GIL 之后,业务共享数据同样需要正确同步。

参考资料

  • 国内:廖雪峰:多线程:采用线程共享状态和锁的解释,说明为什么业务流程仍需同步;其中 GIL 的旧式调度描述不代表当前 CPython。
  • 国内:骆昊:Python 中的并发编程之一:采用线程、进程和 GIL 限制的对比,说明“存在多个线程”和“Python 计算能多核并行”是不同问题。
  • 国内:骆昊:Python 中的并发编程之二:采用计算任务拆分与多进程的讨论,解释在启用 GIL 的常见场景中,为什么多进程是可考虑的方案,以及它对任务划分的要求。
  • 国外:Python:Thread states and the global interpreter lock:采用引用计数竞争、持锁访问 Python 对象和释放 GIL 的规定,解释 GIL 保护的内容及 I/O、原生计算的边界。
  • 国外:Python:Python support for free threading:采用构建方式、运行状态、扩展兼容性与线程安全说明,解释当前 CPython 的可选自由线程支持,以及为什么关闭 GIL 仍需要同步。

相关面经

10 篇

水滴公司

AI 全栈工程师
校招秋招一面、二面
查看原面经 →
Python 这块有个 GIL 做多线程,你了解吗?

蚂蚁集团

AI Agent 应用工程师
查看原面经 →
Python GIL是什么,解释多线程不能跑满多核的原因

滴滴

Java 开发工程师
一面
查看原面经 →
Python 的 GIL 是什么机制?

卓望

全栈开发岗
校招
查看原面经 →
Python中的GIL是什么?能不能进一步解释它的作用?

拼多多

后端开发工程师(AI / Agent 方向)
三面
查看原面经 →
延伸问题
GIL全局解释器锁产生的原因?
展开剩余 5 篇面经

阶跃星辰

大模型基础设施工程师(数据管道)
实习秋招一面、二面
查看原面经 →
GIL机制

字节跳动

Agent 开发
一面
查看原面经 →
Python多线程:为什么有GIL?多线程的锁有哪些?Lock和RLock有啥区别?

腾讯

后端开发工程师(AI)
实习
查看原面经 →
Python 的 GIL 锁是什么?

腾讯

后端开发工程师
一面
查看原面经 →
为什么说 python 是单线程?

字节跳动

Agent 开发
暑期实习一面
查看原面经 →
python有没有多线程?为什么要有GIL,有没有了解过?多线程的锁都有什么?lock和Rlock有什么区别?

收录题集

2 个来源,共2 份题集

相关题目

4 题