Python 对自由线程的支持
***********************

从 3.13 发布版开始，CPython 支持 *free threading* 的 Python 构建，其禁
用 *global interpreter lock* (GIL)。自由线程化的执行允许在可用的 CPU
核心上并行运行线程，充分利用可用的处理能力。 尽管并非所有软件都能自动
地从中受益，但是考虑到线程设计的程序在多核硬件上运行速度会更快。

某些第三方包，特别是带有 *extension module* 的包，可能尚不适用于自由线
程构建版，并将重新启用 *GIL*。

本文档描述了自由线程对 Python 代码的影响。请参阅 自由线程的 C API 扩展
支持 了解如何编写支持自由线程构建的 C 扩展。

参见: **PEP 703** —— 查阅《在 CPython 中使全局解释器锁成为可选项》以了解对
    自由线程 Python 的整体描述。


安装
====

从 Python 3.13 开始，官方 macOS 和 Windows 安装器提供了对可选安装自由
线程 Python 二进制文件的支持。安装器可在
https://www.python.org/downloads/ 获取。

有关其他平台的信息，请参阅 Installing a Free-Threaded Python，这是一份
由社区维护的针对安装自由线程版 Python 的安装指南。

当从源码构建 CPython 时，应使用 "--disable-gil" 配置选项以构建自由线程
Python 解释器。


识别自由线程 Python
===================

要判断当前解释器是否支持自由线程，可检查 "python -VV" 和 "sys.version"
是否包含 "free-threading build"。新的 "sys._is_gil_enabled()" 函数可用
于检查在运行进程中 GIL 是否确实被关闭。

"sysconfig.get_config_var("Py_GIL_DISABLED")" 配置变量可用于确定构建是
否支持自由线程。 如果该变量设置为 "1"，则构建支持自由线程。这是与构建
配置相关的决策的推荐机制。


自由线程版 Python 中的全局解释器锁
==================================

CPython 的自由线程构建版支持在运行时使用环境变量 "PYTHON_GIL" 或命令行
选项 "-X gil" 选择性地启用 GIL。

GIL 也可能在导入未显式标记为支持自由线程模式的 C-API 扩展模块时被自动
启用。在这种情况下将会打印一条警告。

在单独软件包的文档以外，还有下列网站在追踪热门软件包对自由线程模式的支
持状态：

* https://py-free-threading.github.io/tracking/

* https://hugovk.github.io/free-threaded-wheels/


线程安全
========

自由线程构建的 CPython 旨在 Python 层级提供与默认全局解释器锁启用构建
相似的线程安全行为。内置类型（如 "dict"、 "list" 和 "set" 等）使用内部
上锁来防止并发修改，其行为方式与全局解释器锁相似。但是，Python 历来不
对这些内置类型的并发修改提供特定的行为保证，因此这应被视为对当前实现的
描述，而不是对当前或未来行为的保证。

备注:

  建议尽可能使用 "threading.Lock" 或其他同步原语，而不是依赖内置类型的
  内部锁。


已知的限制
==========

本节介绍自由线程 CPython 构建的已知限制。


永生化
------

在自由线程构建中，某些对象属于 *immortal* 对象。永生对象不会被释放且具
有永远不会被修改的引用计数。 这样做是为了避免发生可能妨碍高效的多线程
伸缩调整的引用计数争夺问题。

对于 3.14 发布版，永生对象只限于：

* 代码常量：数字字面值，字符串字面值，以及由其他常量组成的元组字面值。

* 由 "sys.intern()" 所内化的字符串。


帧对象
------

从一个 帧对象 访问 "frame.f_locals" 是不安全的，如果该帧目前是在另一个
线程中执行的话，这样做可能会导致解释器崩溃。


迭代器
------

从多个线程并发地访问同一个迭代器对象通常不是线程安全的，可能导致各个线
程中出现重复或丢失的元素。


单线程性能
----------

自由线程构建在执行 Python 代码时相比默认启用 GIL 的构建会有额外的开销
。具体的开销取决于工作量和硬件环境。在 pyperformance 基准测试套件中，
平均开销增幅在 macOS aarch64 上约为 1% 而在 x86-64 Linux 系统上约为 8%
。


行为的变化
==========

本节描述 CPython 在自由线程构建时的行为变化。


上下文变量
----------

在自由线程构建中，"thread_inherit_context" 标志默认设置为 true，这会导
致使用 "threading.Thread" 创建的线程以 "start()" 的调用程序的
"Context()" 的副本启动。在默认启用 GIL 的构建中，该标志默认为 false，
因此线程以空 "Context()" 启动。


警告过滤器
----------

在自由线程构建中，"context_aware_warnings" 标志默认设置为 true。在默认
启用 GIL 的构建中，该标志默认设置为 false。如果该标志为 true，则
"warnings.catch_warnings" 上下文管理器使用上下文变量用于警告过滤器。如
果该标志为 false，则 "catch_warnings" 修改全局过滤器列表，这不是线程安
全的。详情请参阅 "warnings" 模块。
