golang atomic包的使用

作者: 吃猫的鱼0 | 来源:发表于2018-01-04 11:09 被阅读86次

go语言提供的原子操作都是非侵入式的,它们由标准库代码包sync/atomic中的众多函数代表。

   我们调用sync/atomic中的几个函数可以对几种简单的类型进行原子操作。这些类型包括int32,int64,uint32,uint64,uintptr,unsafe.Pointer,共6个。这些函数的原子操作共有5种:增或减,比较并交换、载入、存储和交换它们提供了不同的功能,切使用的场景也有区别。

增或减

   顾名思义,原子增或减即可实现对被操作值的增大或减少。因此该操作只能操作数值类型。

   被用于进行增或减的原子操作都是以“Add”为前缀,并后面跟针对具体类型的名称。

//方法源码
func AddUint32(addr *uint32, delta uint32) (new uint32)

栗子:(在原来的基础上加n)

atomic.AddUint32(&addr,n)

栗子:(在原来的基础上加n(n为负数))

atomic.AddUint32(*addr,uint32(int32(n)))
//或
atomic.AddUint32(&addr,^uint32(-n-1))

比较并交换

   比较并交换----Compare And Swap 简称CAS

   他是假设被操作的值未曾被改变(即与旧值相等),并一旦确定这个假设的真实性就立即进行值替换

   如果想安全的并发一些类型的值,我们总是应该优先使用CAS

//方法源码
func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)

栗子:(如果addr和old相同,就用new代替addr)

ok:=atomic.CompareAndSwapInt32(&addr,old,new)

载入

   如果一个写操作未完成,有一个读操作就已经发生了,这样读操作使很糟糕的。

   为了原子的读取某个值sync/atomic代码包同样为我们提供了一系列的函数。这些函数都以"Load"为前缀,意为载入。

//方法源码
func LoadInt32(addr *int32) (val int32)

栗子

fun addValue(delta int32){
    for{
        v:=atomic.LoadInt32(&addr)
        if atomic.CompareAndSwapInt32(&v,addr,(delta+v)){
            break;
        }
    }
}

存储

   与读操作对应的是写入操作,sync/atomic也提供了与原子的值载入函数相对应的原子的值存储函数。这些函数的名称均以“Store”为前缀

   在原子的存储某个值的过程中,任何cpu都不会进行针对进行同一个值的读或写操作。如果我们把所有针对此值的写操作都改为原子操作,那么就不会出现针对此值的读操作读操作因被并发的进行而读到修改了一半的情况。

   原子操作总会成功,因为他不必关心被操作值的旧值是什么。

//方法源码
func StoreInt32(addr *int32, val int32)

栗子

atomic.StoreInt32(被操作值的指针,新值)
atomic.StoreInt32(&value,newaddr)

交换

   原子交换操作,这类函数的名称都以“Swap”为前缀。

   与CAS不同,交换操作直接赋予新值,不管旧值。

   会返回旧值

//方法源码
func SwapInt32(addr *int32, new int32) (old int32)

栗子

atomic.SwapInt32(被操作值的指针,新值)(返回旧值)
oldval:=atomic.StoreInt32(&value,newaddr)

相关文章

  • golang atomic包的使用

    go语言提供的原子操作都是非侵入式的,它们由标准库代码包sync/atomic中的众多函数代表。 我们调用syn...

  • JAVA并发-Atomic包

    Atomic包核心 Atomic包里的类基本都是使用Unsafe实现的包装类,核心操作是CAS原子操作。compa...

  • 理解CAS(Compare And Swap)

    原子包java.util.concurrent.atomic使用了CAS 用一个小例子看一下atomic类的线程安...

  • Golang sync.atomic 相比 sync.Mutex

    sync.atomic Golang 标准库中的 sync/atomic 为开发者提供了对几种简单类型的原子操作函...

  • Go 原子操作

    本文讲解 golang 中 sync.atomic 的常见操作 atomic 提供的原子操作能够确保任一时刻只有一...

  • APUE 进程环境

    本文使用golang的syscall,os,golang.org/x/sys/unix包 1.main函数 mai...

  • golang 读写二进制文件(2)

    golang 使用encoding/gob包读写二进制文件 上篇介绍了使用"encoding/binary"包读写...

  • golang解析json数据

    golang官方包encoding/json包解析json数据太复杂,这里使用简单的json解析包simplejs...

  • 知识分享之Golang——fmt 打印常用命令整理

    知识分享之Golang——fmt包常用命令整理 背景 知识分享之Golang篇是我在日常使用Golang时学习到的...

  • atomic的使用,原子操作

    atomic是最轻量级的锁,在一些场景下直接使用atomic包还是很有效的。 下面内容摘秒自《GO并发编程实战》—...

网友评论

    本文标题:golang atomic包的使用

    本文链接:https://www.haomeiwen.com/subject/qexrnxtx.html