本文档解释了 CPython 中的解释器状态和全局解释器锁 (GIL),它们构成了 Python 并发模型的基础。解释器状态维护着一个 Python 解释器实例的全局状态,而 GIL 通过一次只允许一个线程执行 Python 字节码来确保线程安全。有关 Python 3.13 中引入的更近期的自由线程模式的信息,请参阅本文档的最后一部分。
解释器状态 (PyInterpreterState) 是一个结构,用于维护 Python 解释器实例的全局状态。它管理模块、内置函数、线程状态以及其他解释器范围内的资源。CPython 可以在单个进程中支持多个解释器——每个解释器都有自己的全局状态。
全局解释器锁 (GIL) 是一个互斥锁,可防止多个原生线程同时执行 Python 字节码。它是保护 CPython 内存管理和对象系统免受竞态条件影响的机制。在任何给定时间,只有一个线程可以持有 GIL,这意味着即使在多核系统上,CPython 的多线程也仅限于 Python 代码的并发执行,而非并行执行。
来源:Python/pystate.c Python/ceval_gil.c Include/internal/pycore_interp.h Include/internal/pycore_runtime.h
解释器状态代表一个单一的 Python 解释器,其中包含需要在该解释器内的所有线程之间可见的全局状态。CPython 将每个解释器的状态保存在 PyInterpreterState 结构中。
PyInterpreterState 结构包括:
| 组件 | 描述 |
|---|---|
id | 解释器的唯一标识符 |
runtime | 指向运行时状态的引用 |
threads | 属于此解释器的线程状态 |
builtins | 内置对象字典 |
sysdict | 系统模块字典 |
modules | 已导入模块的字典 |
gc | 垃圾回收状态 |
ceval | 求值和 GIL 相关状态 |
imports | 导入相关状态 |
feature_flags | 功能标志设置(线程、fork 等) |
obmalloc | 内存分配器状态 |
运行时状态 (_PyRuntimeState) 是一个全局结构,其中包含所有 Python 解释器、线程状态信息和全局锁。主解释器是一个特殊的解释器实例,它在 Python 启动时自动创建,并通过运行时状态访问。
来源:Python/pystate.c585-704 Include/internal/pycore_interp.h Include/internal/pycore_runtime_init.h122-154
GIL 是一种互斥锁,在任何给定时间只允许一个线程持有 Python 解释器的控制权。它的主要目的是简化内存管理并避免 CPython 引用计数系统中的竞态条件。
CPython 中的 GIL 实现包括:
gil->mutex)gil->cond)gil->locked)gil->last_holder)来源:Python/ceval_gil.c147-191 Python/ceval_gil.c203-254
核心的 GIL 操作包括:
获取 GIL (take_gil)
释放 GIL (drop_gil)
来源:Python/ceval_gil.c284-360 Python/ceval_gil.c203-254
线程状态 (PyThreadState) 负责跟踪 Python 解释器内的线程特定数据。与 Python 交互的每个线程都有自己的线程状态结构。
线程状态包括:
| 组件 | 描述 |
|---|---|
interp | 指向解释器状态的引用 |
next/prev | 线程状态的双向链表 |
holds_gil | 指示线程是否持有 GIL 的标志 |
current_frame | 指向当前执行帧的指针 |
state | 线程状态(已连接、已断开、已挂起) |
py_recursion_remaining | 递归限制控制 |
tracing | 跟踪/性能分析状态 |
c_profilefunc | C 性能分析函数 |
c_tracefunc | C 跟踪函数 |
eval_breaker | 用于中断解释器循环的标志 |
线程状态会经历几个阶段:
来源:Python/pystate.c250-301 Include/cpython/pystate.h66-186 Include/internal/pycore_pystate.h44-47
Python 解释器的生命周期包括创建、初始化和最终化阶段。
PyInterpreterState 结构当不再需要解释器时,它会经过一个最终化过程:
来源:Python/pystate.c615-704 Python/pystate.c812-947 Python/pylifecycle.c611-677
Python 3.13 引入了对自由线程模式的实验性支持,在这种模式下可以禁用 GIL。这允许在多个 CPU 核心上真正并行执行 Python 代码。
自由线程模式带来了重大变化:
--disable-gil 禁用 GIL自由线程模式:
python3.13t)--disable-gil 选项从源代码构建C 扩展在自由线程模式下需要特殊处理
Py_mod_gil 插槽来指示 GIL 支持PyUnstable_Module_SetGIL 的单阶段初始化扩展来源:Doc/whatsnew/3.13.rst306-352 Include/object.h147-163 Python/pystate.c260-299
解释器状态和 GIL 是 CPython 执行模型的基础。解释器状态维护着 Python 代码执行的全局资源和上下文,而 GIL 以牺牲并行执行为代价,确保了线程安全。随着 Python 3.13 中引入的自由线程模式,CPython 正在开始探索 GIL 的替代方案,这有望在未来实现真正的并行性,尽管目前这仍然是实验性的。
对于 Python 扩展开发者来说,理解这些组件至关重要,特别是那些需要处理线程或开发需要与解释器进行低级交互的模块的开发者。