python原子_Python的原子性操作是如何实现的

GIL保证字节码级别的原子性和线程安全性,因此当个字节码执行一定是安全的,执行结果一定是一致的。

而有些操作,底层需要通过多个字节码来完成,这样的操作就不是原子的,因此不是线程安全的。举个例子,a+=1 。反编译这个语句,发现它由4个字节码组成:>>> dis.dis(compile('a+=1', '', 'exec'))

1 0 LOAD_NAME 0 (a)

2 LOAD_CONST 0 (1)

4 INPLACE_ADD

6 STORE_NAME 0 (a)

8 LOAD_CONST 1 (None)

10 RETURN_VALUE

这个简单的语句,背后需要 4 个字节码协作完成:LOAD_NAME 将 a 当前的值加载进运行栈;

LOAD_CONST 将常量 1 加载到运行栈;

INPLACE_ADD 对栈上两个操作数进行加法运算;

STORE_NAME 将计算结果保存;

如果你学过汇编的话,你会发现Python字节码跟汇编指令非常像!GIL保证当个字节码的执行不会受到其他线程的任何干扰,但是任何字节码间都可能发生线程切换。

假设两个线程同时自增变量a,a当前值为0;线程A执行到第3步,自增结果1已算出,但未保存;这时线程B得到调度开始执行,同样算出结果1并抢先保存了;A回过头来将结果1保存,B的结果被覆盖了,最终a的值是1。然而,两个线程对a自增,它的值讲道理应该是2!这就是并发操作产生的竞争态,解决方法是用一个锁将这几个字节码作为原子操作保护起来。

我写过一个关于Python虚拟机内部实现的专栏Python源码深度剖析,里面有些许介绍,有兴趣可以看看~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值