本页面将介绍 Python 的并发方法,特别关注 Python 3.13 中引入的实验性 free-threading 模式。有关多进程和其他并发执行方法的信息,请参阅 Python 的标准库并发模块。
CPython,Python 的参考实现,传统上使用全局解释器锁 (GIL) 来同步对 Python 对象的访问。此锁阻止多个原生线程同时执行 Python 字节码。虽然 GIL 简化了内存管理并防止了竞态条件,但它也限制了使用基于线程的并行性来利用多个 CPU 核心的能力。
Python 3.13 引入了一个实验性的“free-threading”模式,允许 Python 在没有 GIL 的情况下运行,从而可以跨多个 CPU 核心真正并行执行 Python 线程。
来源: Doc/whatsnew/3.13.rst306-352
GIL 是一个互斥锁,可确保一次只有一个线程在 Python 解释器中执行 Python 字节码。当一个线程想要执行 Python 代码时,它必须先获取 GIL。如果另一个线程已经持有 GIL,则请求的线程必须等待 GIL 被释放。
GIL 在 CPython 中通过 _gil_runtime_state 结构实现,该结构包含
locked:一个原子整数标志,指示 GIL 当前是否被持有gil_mutex:一个用于控制对 GIL 访问的互斥锁gil_cond:一个用于线程等待 GIL 的条件变量last_holder:指向最后一个持有 GIL 的线程状态的指针为防止单个线程垄断 GIL,Python 实现了一种协作式线程切换机制
gil_drop_request 标志来源: Python/ceval_gil.c49-144 Python/ceval_gil.c202-275
Python 3.13 引入了基于 PEP 703 的实验性无 GIL 运行支持。这使得多个线程可以在不同的 CPU 核心上并行执行 Python 代码,从而可能提高 CPU 密集型多线程代码的性能。
Free-threading 模式需要特殊的构建配置
python3.13t 或 python3.13t.exe)--disable-gil 选项从源代码构建 Python。即使使用 free-threaded 构建,您也可以在运行时控制 GIL。
PYTHON_GIL=1 来启用 GIL。-X gil=1 来启用 GIL。sys._is_gil_enabled() 检查当前进程中是否启用了 GIL。来源: Doc/whatsnew/3.13.rst306-347 Python/pylifecycle.c543-574
为了支持 free-threading,CPython 的内存管理进行了重大更改。
ob_ref_local) 和共享原子 (ob_ref_shared) 引用计数。ob_mutex) 用于同步。CPython 的并发模型围绕几个关键结构构建。
_PyRuntimeState):整个 Python 进程的全局状态。PyInterpreterState):Python 解释器实例的状态。PyThreadState):执行 Python 代码的线程的状态。PyThreadState 结构保存线程特定的数据。
interp)current_frame)_status),包括 initialized、bound、activeholds_gil)eval_breaker)在 free-threading 模式下,还会使用额外的线程管理状态。
_Py_THREAD_ATTACHED:线程正在运行 Python 代码。_Py_THREAD_DETACHED:线程未运行 Python 代码。_Py_THREAD_SUSPENDED:线程已暂停(例如,用于垃圾回收)。来源: Python/pystate.c44-107 Include/internal/pycore_pystate.h43-47
C 扩展模块需要显式指示其与 free-threading 的兼容性。
对于多阶段初始化,请使用 Py_mod_gil 插槽。
对于单阶段初始化,请使用 PyUnstable_Module_SetGIL。
导入 C 扩展时:
来源: Doc/whatsnew/3.13.rst332-341
Free-threading 模式提供了性能上的权衡。
在考虑 free-threading 模式时:
来源: Doc/whatsnew/3.13.rst318-325
要有效地使用 free-threading 模式:
python -VV 将显示“experimental free-threading build”。sys._is_gil_enabled() 返回 GIL 是否已启用。PYTHON_GIL=1(启用)或 PYTHON_GIL=0(禁用)。-X gil=1(启用)或 -X gil=0(禁用)。来源: Doc/whatsnew/3.13.rst327-331
Free-threading 模式在 Python 3.13 中是实验性的,并且很可能在未来的版本中发展。关键的改进领域包括:
虽然对 CPU 密集型应用程序前景看好,但在经过彻底测试之前,不建议在生产环境中使用 free-threading。