同时更新变量总是不安全的吗?

时间:2015-12-04 13:54:01

标签: python multithreading locking

在多线程环境中,在修改变量值之前应使用locking以避免并发写入。

这适用于所有类型的变量吗?我特别想到的是dict键的值由不同的线程更新的情况(可能同时,每个线程都是不同键的值)。

4 个答案:

答案 0 :(得分:2)

直接In [4]: import dis In [5]: x = {} In [6]: def f(): ...: x['test'] = 'test' ...: In [7]: dis.dis(f) 2 0 LOAD_CONST 1 ('test') 3 LOAD_GLOBAL 0 (x) 6 LOAD_CONST 1 ('test') 9 STORE_SUBSCR #<<<<<<<< this OP 10 LOAD_CONST 0 (None) 13 RETURN_VALUE 分配是线程安全的

GIL仅在python字节码指令之间产生。只接受单个字节码指令的操作对于GIL中间操作是安全的。 public static float ToSingle(double value) { return (float)value; } 作业只需一次操作。

{{rec.lotti}}

如果您需要除写入以外的任何内容 - 就地添加,读取后写入等 - 那么您就遇到了麻烦。

我强烈反对这是一个实现细节,实际上取决于它,以保证行为是在寻找麻烦。始终提供围绕共享数据访问的显式锁定。

答案 1 :(得分:1)

在您的情况下,您只是更改与键关联的值,这是对字典的操作。 dict结构本身是线程安全的,请参见此处:Thread Safety in Python's dictionary所以你应该没问题。

如果您在字典中存储的对象内进行更改,那么可能是安全的,但可能不是。如果一个线程一次只更改一个特定对象那么这是安全的,但是如果由于某种原因多个线程同时开始访问一个对象它是不安全的。

答案 2 :(得分:0)

我不担心它是否真的是你正在处理的多线程。线程在单个进程(google GIL)中运行,因此并发写入似乎不太可能。

如果您有可能进行多处理,那么在进程之间共享数据会变得更加复杂。

答案 3 :(得分:0)

是的,它本质上是不安全的。即使您对字典中的独立对象进行了更新,并且读取从不与写入同时发生,应用程序的行为也是未定义的。