golang 编程笔记

【golang】利用atomic进行无锁化开发

2020-05-21  本文已影响0人  dongzd

以下是本人在项目经常用到的用法与作用,具体详细介绍可以看详细文档:
http://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E5%8E%9F%E5%AD%90%E6%93%8D%E4%BD%9C%E5%92%8Catomic%E5%8C%85.html

单个指令同步操作

1、并发下,数值计数

var i int64
atomic.AddInt64(&i, 1)

2、并发下,数值赋值

var num int64
atomic.StoreInt64(&num, 222)

3、并发下,数值读取

var num int64
atomic.LoadInt64(&num)

4、并发下,状态变更

var statusCode int64
atomic.CompareAndSwapInt64(&statusCode, 0, 1)

5、并发下,字典map赋值读取

var m sync.Map
m.Store("name", "su")
m.Load("name")

指令集,同步操作

有时产生一个值,需要一系列指令处理,想要对这整个指令集同步,比如加载配置,这时就需要atomic.Value上场。

func Main(){
         var con atomic.Value
        con.Store(LoadConfig())
        c := con.Load()
       fmt.Println(c)
}
func LoadConfig() map[string]string {
    fmt.Println("开始获取配置处理")
    m := make(map[string]string)
    time.Sleep(1 * time.Second)
    /** 读取配置文件等处理*/
    m["file"] = ""
    fmt.Println("结束配置读取")
    return m
}

我们来看一下,atomic.Value是否是同步一个指令块

func main(){
    go LoadConfig("协程A,加载配置")
    go LoadConfig("协程B,加载配置")

    for {
    }
}
协程A,加载配置
协程B,加载配置
结束配置读取
结束配置读取

可以看出在不使用Lock()下是同时进行的,但我们要求的是无锁化,加上atomic.Value试一下

func Main(){
        var con atomic.Value
        go con.Store(LoadConfig("协程A,加载配置"))
        go con.Store(LoadConfig("协程B,加载配置"))
}
协程A,加载配置
结束配置读取
协程B,加载配置
结束配置读取

因为atomic是在底层实现同步的,不能中断,比系统实现的mutex等锁性能消耗低。

上一篇下一篇

猜你喜欢

热点阅读