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

Python有GIL为何仍需线程同步?竞态条件成因解惑

GIL下Python多线程竞态条件的成因解释

GIL的定义

根据维基百科对GIL的定义:

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread-safe.

问题背景

很多人会误以为,因为CPython的GIL同一时间只允许一个线程执行Python字节码,所以多线程操作共享变量时不会出现竞态条件,不需要做线程同步。但实际运行如下代码时,却出现了竞态条件,得到不符合预期的结果:

示例代码

import threading

# global variable x
x = 0

def increment():
    """
    function to increment global variable x
    """
    global x
    x += 1

def thread_task():
    """
    task for thread
    calls increment function 100000 times.
    """
    for _ in range(100000):
        increment()

def main_task():
    global x
    # setting global variable x as 0
    x = 0

    # creating threads
    t1 = threading.Thread(target=thread_task)
    t2 = threading.Thread(target=thread_task)

    # start threads
    t1.start()
    t2.start()

    # wait until threads finish their job
    t1.join()
    t2.join()

if __name__ == "__main__":
    for i in range(10):
        main_task()
        print("Iteration {0}: x = {1}".format(i,x))

运行输出

Iteration 0: x = 175005
Iteration 1: x = 200000
Iteration 2: x = 200000
Iteration 3: x = 169432
Iteration 4: x = 153316
Iteration 5: x = 200000
Iteration 6: x = 167322
Iteration 7: x = 200000
Iteration 8: x = 169917
Iteration 9: x = 153589

成因解释

核心原因在于:GIL保证的是同一时间只有一个线程执行Python字节码,但单个Python语句(比如x += 1)并不是原子操作。

x += 1在底层会被拆解成三个独立的字节码指令:

  • 加载全局变量x的值到栈顶(LOAD_GLOBAL x)
  • 将栈顶的值加1(INPLACE_ADD)
  • 将计算结果存回全局变量x(STORE_GLOBAL x)

GIL会在字节码执行的间隙释放(比如执行完一定数量的字节码后,或者遇到I/O操作时)。假设线程A执行完前两个字节码(已经把x的值加载并加1),此时GIL被释放,线程B获得GIL并执行完整的三个字节码,把x的值更新。之后线程A重新获得GIL,执行第三个字节码,把自己之前计算的结果存回x,这就覆盖了线程B的更新,导致最终x的数值比预期的200000小。

简单说,GIL只保护字节码级别的原子性,但用户层面的单个语句可能对应多个字节码,这些字节码之间可能被其他线程打断,从而引发竞态条件。因此,多线程操作共享变量时,仍然需要使用线程同步机制(比如threading.Lock)来保证操作的原子性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:20:16