为什么Python'list'的'append'方法是原子的,而i = i + 1不是原子的?

问题描述 投票:2回答:1

根据 Python文档జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ append 在Python上的操作 list 是原子性的。同时加法运算也不是原子的。

i = i + 1

我知道Python GIL是在强制执行 append 操作是原子的。我的问题是,为什么GIL没有对加法操作执行同样的规定?

请看下面的代码。

In [24]: L = []

In [25]: def func1():
    ...:     L.append(2)
    ...:

In [26]: i = 0

In [27]: def func2():
    ...:     i = i + 2
    ...:

两个函数的字节码如下图所示。

In [28]: dis.dis(func1)
  2           0 LOAD_GLOBAL              0 (L)
              2 LOAD_METHOD              1 (append)
              4 LOAD_CONST               1 (2)
              6 CALL_METHOD              1
              8 POP_TOP
             10 LOAD_CONST               0 (None)
             12 RETURN_VALUE

In [29]: dis.dis(func2)
  2           0 LOAD_FAST                0 (i)
              2 LOAD_CONST               1 (2)
              4 BINARY_ADD
              6 STORE_FAST               0 (i)
              8 LOAD_CONST               0 (None)
             10 RETURN_VALUE

Python 确保线程切换只发生在字节码指令之间。字节码指令的不同之处是什么,使得 append 操作是原子的?

python thread-safety atomic gil
1个回答
0
投票

因为 append 操作会对被追加的列表产生副作用,如果不是原子性的,它将没有任何语义的机会(而且很有可能甩掉核心)。相比之下,加法的过程要简单得多,而且也是换算的,所以在一个线程中做i+=1,在另一个线程中做i-=1,当硝烟散尽时,最终结果是一样的。

© www.soinside.com 2019 - 2024. All rights reserved.