《Go并发编程实战》学习记录-原子操作

原子操作

定义:

原子操作即执行过程中不能被中断的操作。在针对某个值的原子操作执行过程中,CPU绝对不会再去执行其他针对该值的操作。

增或减

原子增/减操作即可实现被操作值的增大和减小

用于增或减的原子操作,函数名称已Add为前缀,后跟具体类型的名称:

newi32 := atomic.AddInt32(&i32,3)

第一个参数必须是指针类型,代表被操作值在内存中的存放位置,以便施加特殊CPU指令。

第二个参数与被操作值的类型相同

PS: 注意 AddUnit32AddUnit64方法,因为unit类型无法为负值,无法传递一个负值来进行减小操作。

atomic.AddUint32(&ui32,^uint32(-NN-1))

原理是利用二进制补码的特性。一个负整数的补码可以通过对它按位求反码并+1得到

比较并交换

比较并交换即"Compare And Swap",简称 “CAS”。在sync/atomic包中,已CompareAndSwap为前缀的函数代表。

func CompareAndSwapInt32(addr *int32,old,new int32)(swaped bool)

  1. 第一个参数是被操作数的指针值
  2. 第二个参数代表原值
  3. 第三个参数代表新值
  4. 返回值代表是否交换成功

CAS操作优势是:在不创建互斥量和不形成临界区的情况下,完成并发安全的值替换操作,大大减少性能损耗。

并发情况下,old值不一定能匹配上,需要使用for循环来多次尝试。

载入

原子的读取某个值

sync/atomic包提供了一系列函数,以Load为前缀

atomic.LoadInt32(value &int32)(v int32)

只接受一个为函数相同类型的指针值,返回值为读取的该被操作值

存储

sync/atomic提供了与读取相对应的存储操作函数,以Store为前缀

atomic.StoreInt32(&i32,1)

  1. 第一个参数是被操作值的指针
  2. 第二个参数是存储的值,与被操作值同类型

交换

原子交换操作,这类函数已Swap为前缀。

与CAS操作不同,交换操作不关心旧值,直接设置为新值,返回旧值。

atomic.SwapInt32(&int32,int32) int32

  1. 参数1是被操作的值的指针
  2. 第二个是新值
  3. 返回值为旧值

原子值

sync/atomic.Value 是一个结构体类型,称为 “原子值类型”,用于保存需要原子读取的值。

可接受的被操作值的类型不限。

该类型有两个指针方法LoadStore

Store方法有两个限制:

  1. 作为参数,传入方法的值不能为nil
  2. 作为参数传入的值,比如与之前传入的值类型相同

由于对原子值的读写操作必是原子的,同时又不接受操作值类型的限制,因此它比原子函数的适用场景大很多。有些时候,可以完美替换锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值