无GIL的CPython 3.13+中修改对象整数字段是否会破坏解释器?
无GIL的CPython 3.13+中纯Python代码的线程安全性疑问
自CPython 3.13起,全局解释器锁(GIL)已支持禁用。我想明确在无GIL环境运行时,哪些操作属于「安全」范畴——此处的「安全」特指不会导致解释器崩溃或状态损坏。
具体来看下面的示例代码:定义一个简单类,并通过多线程并行增减该类实例的int类型计数器:
import threading import time class MyObject: def __init__(self): self.counter = 0 def run(self): while True: self.counter += 1 self.counter -= 1 instance = MyObject() for _ in range(10): threading.Thread(target=instance.run).start() while True: print(instance.counter) time.sleep(1)
我清楚无论是否启用GIL,这段无显式锁的代码都存在竞争条件,print(instance.counter)可能输出非零值,且数值可能随时间偏离预期,但这是我可以接受的情况。
我好奇的是,在自由线程化的Python 3.13+环境中,这段代码是否符合上述定义的「安全」,具体疑问如下:
- 访问
instance.counter或self.counter是否会引发段错误、崩溃或解释器状态损坏? - 对
instance.counter执行增减操作是否会引发段错误、崩溃或解释器状态损坏? - 读取、打印、复制或存储
instance.counter是否会得到无法表示的非整数值?
我理解答案可能因实现细节不同而有差异,且可能随版本更新变化。我仅关注完全可控的纯Python对象的数值字段修改场景,也清楚中间层容器或访问逻辑可能影响安全保障。
已尝试操作
- 在本地构建的启用/禁用GIL的解释器中运行上述代码,仅观测到预期的竞争条件,未出现崩溃或非整数值,但可能因运行时长不足或未触发特定内部竞争条件而遗漏问题。
- 阅读了GIL移除相关的PEP 0703文档及面向C扩展开发者的配套文档,未找到针对纯Python代码线程安全的行为不变性说明。
- 了解到无GIL解释器新增了解释器内部锁(会降低单线程性能)以避免部分状态损坏,好奇此场景是否会用到该锁,以及它对崩溃安全和无效中间状态观测的保障程度。
- 我知道可变数据的多线程场景下显式锁是必要的,但我不关注结果正确性,仅在意上述定义的安全性。
提问原因
- 出于个人好奇。
- 担忧所维护的既有代码在无GIL环境下的安全性。
- 希望用这种模式实现用于模糊测试和近似计算的刻意不准确的可变数值。
内容的提问来源于stack exchange,提问作者Zac B
相关产品推荐
相关产品推荐

