翻阅 Python文档 可以得知,Python中某些操作如 list.append(item)
是原子性操作,在多个线程对一个列表执行添加是线程安全的。
大致翻译如下
什么样的全局值突变是线程安全的?
全局解释器锁(GIL)在内部使用,以确保每次只有一个线程在pythonvm中运行。一般来说,Python只提供在字节码指令之间的线程间切换;它的切换频率可以通过sys.setswitchinterval()
来改变。 因此,从Python程序的角度来看,每个字节码指令以及从每个指令的所有用C实现的代码都是原子性的。
从理论上讲,这意味着精确的计算需要对PVM字节码的实现有一个准确的理解。实际上,这意味着对内置数据类型(int、list、dict等)的共享变量的操作实际上是“原子”的。
以下是原子性的:
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是如何将诸如“删除列表中一个元素”
,“给一个整型变量赋值”
,“给列表添加一个元素”
的操作封装成具有原子性
的操作。
按道理,以上操作应该都经历读取地址
,写入数据
的过程,在 GIL 的作用下,Python中每次只允许一个线程工作。
假设以上操作不是原子性的,那么每个线程的分片用完
时有可能只是才执行完读取地址
的阶段,还没来得及写入数据
就轮到下一个线程了,这样就线程不安全了,但是实际上并不会发生这种情况。
所以会不会是Python对以上操作执行添加了PV操作
呢?或者是加了个锁
?
但是问题又来了,如果仅仅是单线程处理
,或者是对数组切片并多线程处理
,这岂不是非常损耗性能?
以上便是我的困惑与思考,希望能得到解答,十分感谢啦~
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…