Atomic实现:变量的原子操作

使用场景

多个goroutine里面安全访问共享变量

核心实现逻辑

  1. 通过系统的CPU指令来保证对变量的原子操作,如i386的LOCK指令

atomic实现

  1. 代码主要包含如下功能,实际为三种类型,通用类型Value、通用型函数、对第一种类型的封装

    • 通用型函数
      • Swap函数功能:将数据原子替换
      • CompareAndSwap: 对比数据后将数据原子替换
      • Add:原子增加数据
      • Load:原子加载数据
      • Store:原子存储数据
    • 通用型函数,也是对第一种类型的封装
      • 更加通用的实现,Struct Value:该struct也实现了上面的各种函数,Value里的参数包含v any
    • 对第一种类型的封装,使用更加方便明确,通过noCopy声明不能内嵌
      • type.go里面定义一些常用类型的实现,Bool、Pointer(泛型)、Int32、Int64、Uint32、Uint64、Uintptr,实际调用的是上面的Swap等一系列函数
  2. 代码实现

    • 用户调用,调用doc.go
    • 实际调用同目录下的汇编代码asm.s
    • 汇编代码asm.s调用到runtime∕internal∕atomic下的汇编代码
    • AddInt32对应runtime∕internal∕atomic·Xadd
    • 对应runtime/internal下的atomic_{arch}.go文件,可以通过arch命令查看当前的系统是什么
    • runtime/internal下的atomic_{arch}.go对应runtime/internal下的atomic_{arch}.s文件
    • 不同的系统,有不同的实现
  3. 函数实现例子

  • sync/doc.go,里面为用户调用golang的入口
    func AddInt32(addr *int32, delta int32) (new int32)
    
  • sync目录有个asm.s,里面有对应上面函数的汇编实现
    TEXT ·AddInt32(SB),NOSPLIT,$0
    JMP	runtime∕internal∕atomic·Xadd(SB)
    
  • 对应runtime∕internal∕下的atomic_{arch}.go函数
    func Xadd(ptr *uint32, delta int32) uint32
    
  • 对应runtime∕internal∕下的atomic_{arch}.s函数,主要是LOCK指令,保证原子性,下面是i386系统的代码
    TEXT ·Xadd(SB), NOSPLIT, $0-12
    MOVL	ptr+0(FP), BX
    MOVL	delta+4(FP), AX
    MOVL	AX, CX
    LOCK
    XADDL	AX, 0(BX)
    ADDL	CX, AX
    MOVL	AX, ret+8(FP)
    RET
    

思考

  1. 已经有Mutex,为什么要atomic?
    使用场景不太一样,Mutex主要是对一段代码的加锁,atomic主要是对共享变量的原子操作。

参考

  1. https://kunkkawu.com/archives/shen-ru-li-jie-golang-de-atomic-yuan-zi-cao-zuo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值