美文网首页golang 编程笔记
【golang】利用atomic进行无锁化开发

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

作者: dongzd | 来源:发表于2020-05-21 09:13 被阅读0次

    以下是本人在项目经常用到的用法与作用,具体详细介绍可以看详细文档:
    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等锁性能消耗低。

    相关文章

      网友评论

        本文标题:【golang】利用atomic进行无锁化开发

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