python中哪些操作是原子性的
python 多线程使用过程中,可能有时候我们想知道哪些操作是原子性的,哪些不是,官网给我们列举了常见的几种:
L, L1, L2 are lists, D, D1, D2 are dicts, x, y are objects, i, j are ints
下面这些都是原子操作:
L.append(x)
L1.extend(L2)
x = L[i]
x = L.pop()
L1[i:j] = L2
L.sort()
x = y
x.field = y
D[x] = y
D1.update(D2)
D.keys()
下面这些则不是原子操作:
i = i+1
L.append(L[-1])
L[i] = L[j]
D[x] = D[x] + 1
这里要注意的一点是,我们有时会听到说 python 中的 list 对象不是线程安全的,这个说法是不严谨的,因为线程是否安全,针对的不是对象,而是操作。
如果我们指这样的操作L[0] = L[0] + 1
,它当然不是一个原子操作,不加以保护就会导致线程不安全,而L.append(i)
这样的操作则是线程安全的。
因此列表是可以用作多线程中的存储对象的,但是我们一般不用列表,而使用queue.Queue
,是因为后者内部实现了Condition
锁的通信机制,详情请看这篇文章。