问题描述
参考以下链接:http://docs.python.org/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe
我想知道以下是否:
(x, y) = (y, x)
将在 cPython 中保证原子性.(x 和 y 都是 python 变量)
一起来看看:
>>>x = 1>>>y = 2>>>def swap_xy():... 全局 x, y... (x, y) = (y, x)...>>>dis.dis(swap_xy)3 0 LOAD_GLOBAL 0 (y)3 LOAD_GLOBAL 1 (x)6 ROT_TWO7 STORE_GLOBAL 1 (x)10 STORE_GLOBAL 0 (y)13 LOAD_CONST 0 (无)16 RETURN_VALUE它们似乎不是原子的:x 和 y 的值可以被 LOAD_GLOBAL
字节码之间的另一个线程改变,在 ROT_TWO
之前或之后, 以及 STORE_GLOBAL
字节码之间.
如果你想原子地交换两个变量,你需要一个锁或一个互斥锁.
对于那些需要经验证明的人:
>>>def swap_xy_repeatedly():...而1:... swap_xy()...如果 x == y:... # 如果所有交换都是原子的,那么永远不会有 x == y 的时候.... # (当然,这取决于if x == y"是原子的,它不是;... # 但是如果if x == y"不是原子的,我们对更复杂的东西有什么希望... # "x, y = y, x"?)...打印检测到非原子交换"... 休息...>>>t1 = threading.Thread(target=swap_xy_repeatedly)>>>t2 = threading.Thread(target=swap_xy_repeatedly)>>>t1.开始()>>>t2.start()>>>检测到非原子交换With reference to the following link: http://docs.python.org/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe
I wanted to know if the following:
(x, y) = (y, x)
will be guaranteed atomic in cPython. (x and y are both python variables)
Let's see:
>>> 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
It doesn't appear that they're atomic: the values of x and y could be changed by another thread between the LOAD_GLOBAL
bytecodes, before or after the ROT_TWO
, and between the STORE_GLOBAL
bytecodes.
If you want to swap two variables atomically, you'll need a lock or a mutex.
For those desiring empirical proof:
>>> 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
这篇关于变量交换是否保证在 python 中是原子的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!