参考以下链接:http://docs.python.org/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safepython中的变量保证是原子吗?
我想知道以下几点:
(x, y) = (y, x)
将保证在CPython的原子。 (x和y都是python变量)
参考以下链接:http://docs.python.org/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safepython中的变量保证是原子吗?
我想知道以下几点:
(x, y) = (y, x)
将保证在CPython的原子。 (x和y都是python变量)
让我们来看看:
>>> 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
是的,是的,它会。
Kragen Sitaker 写道:使用成语
spam, eggs = eggs, spam
获得一个线程安全的交换
有人推荐。这真的有用吗? (...)
因此,如果此线程失去第一LOAD_FAST
最后STORE_FAST之间的任何控制,数值可以得到存储在由另一个线程
为“B”,这将被丢失。没有任何东西能够保持这种发生,是吗?没有。一般来说,即使简单的 分配也必然是线程安全的 ,因为执行分配可能会在对象 上调用特殊方法,这些方法本身可能需要操作数 。 希望对象 将内部锁定它的 “状态”值,但这并不总是 的情况。
但它确实在特定 应用什么 “线程安全”是指决定,因为我的脑海里有 是这样 安全的粒度的多层次,所以很难谈 “线程安全”。关于唯一的东西 Python解释器将 免费提供给您的是,即使使用本地线程,内置的 数据类型也应该从内部的 损坏中安全。 换句话说,如果两个线程都
a=0xff
和a=0xff00
,一个最终会 与一个或另一个,但不是 意外0xffff
如可能在其他一些语言 可能的,如果一个 不受保护。随着中说,的Python也趋于 执行这样的方式,你可以 逃脱一个可怕的很多不正规的 锁定,如果你愿意 生活在边缘了一下,有 暗示对实际使用的 对象的依赖关系。沿着这些线在 c.l中有一个体面的 讨论。一会儿回来 - 搜索 groups.google.com中的“Critical 部分和互斥体”线程在 之间。
就个人而言,我显式地锁定在任何多线程应用程序共享 状态(或使用的构建体设计用于 交换共享信息正确 之间线程,如
Queue.Queue
) 。到 我的脑海里它是最好的保护 反对维护和演变下来 的道路。- - David
为什么? GIL?反汇编不建议原子性(见@ jemfinch的答案)。 – kennytm 2010-04-12 15:17:44
(顺便说一下,上面的评论*不是一个反问的问题。) – kennytm 2010-04-12 15:26:06
@Kenny:这是我的部分误解,因为tuple解包是如何在低级别上工作的。 – voyager 2010-04-12 15:33:02