让我们来看看:
>>> x = 1
>>> y = 2
>>> def swap_xy():
... global x, y
... (x, y) = (y, x)
...
>>> dis.dis(swap_xy)
3 0 LOAD_GLOBAL 0 (y)
3 LOAD_GLOBAL 1 (x)
6 ROT_TWO
7 STORE_GLOBAL 1 (x)
10 STORE_GLOBAL 0 (y)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
它不会出现,他们是原子:x的和y的值可以被另一个线程之间改变LOAD_GLOBAL
字节码,之前或之后ROT_TWO
,和之间的STORE_GLOBAL
字节码。
对于那些需要经验证明的人:
>>> def swap_xy_repeatedly():
... while 1:
... swap_xy()
... if x == y:
... # If all swaps are atomic, there will never be a time when x == y.
... # (of course, this depends on "if x == y" being atomic, which it isn't;
... # but if "if x == y" isn't atomic, what hope have we for the more complex
... # "x, y = y, x"?)
... print 'non-atomic swap detected'
... break
...
>>> t1 = threading.Thread(target=swap_xy_repeatedly)
>>> t2 = threading.Thread(target=swap_xy_repeatedly)
>>> t1.start()
>>> t2.start()
>>> non-atomic swap detected