You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Python 3.11多线程代码无竞态条件,修改后却出现?

Python 3.11多线程竞态条件差异解析

现象描述

执行下方多线程代码时,Python 3.11中最终输出的counter值始终等于4000000(无竞态条件),但将代码里的counter += 1修改为counter += int(1)后,竞态条件立即出现,最终结果会小于预期值。

原代码:

import threading
import time

counter = 0

lock = threading.Lock()


def increment():
    global counter

    for _ in range(10**6):
        counter += 1


threads = []
for i in range(4):
    x = threading.Thread(target=increment)
    threads.append(x)

for t in threads:
    t.start()

for t in threads:
    t.join()

print(counter)

原因解析

这是Python 3.10及以上版本新增的字节码优化导致的:

  • 针对counter += 1这类简单整数自增操作,CPython编译器会把它直接优化为单条INPLACE_ADD字节码指令。由于CPython的全局解释器锁(GIL)在执行单条字节码指令期间不会释放,这个自增操作就变成了原子性操作,多线程执行时不会出现竞态。
  • 改成counter += int(1)后,因为int(1)是一个函数调用,编译器无法将整个表达式合并为单条字节码。此时这条语句会被拆分成多个步骤:调用int(1)获取数值、加载counter当前值、执行加法运算、将结果赋值回counter。在这一系列步骤中,GIL可能会被释放,其他线程就有机会在中间阶段修改counter,进而引发竞态条件,导致最终结果小于预期。

内容的提问来源于stack exchange,提问作者RohanAlmighty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 21:29:52