【go】atmoic.Value

本文深入解析了Go语言中atomic.Value类型的源码,详细介绍了其Store和Load操作的内部机制,包括FirstStore模式下对typ指针的初始化及后续的data指针替换过程。同时,探讨了Value类型在周期写、不定时读场景中的应用,如在服务器视图更新中的实例,以及官方给出的map更新示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源代码分析

  • atomic.Value分为两个操作,通过Store()存储Value,通过Load()来读取Value的值.

  • 源码我就不贴了,贴一个关键的struct:

    type ifaceWords struct {
        typ  unsafe.Pointer
        data unsafe.Pointer
    }

    ifaceWords结构体是实际存储我们的Value值的地方,可以看到,我们存储的实际是指向Value的type和data的指针.

  • Store操作有两种行为模式:
    • First Store : 当我们第一次调用Store的时候,Store函数会初始化typ指针(需要注意的是,每一个Value在第一次Store之后typ就被确定而不能更改了,否则会panic).
      如果typ==nil则函数会调用runtime_procPin(没找到实现,但注释中说是active spin wait)
      随后调用原子操作函数CompareAndSwapPointer(typ, nil, unsafe.Pointer(^uintptr(0))),如果此时结果返回false说明typ已经不等于nil(被其他goroutine修改过),于是调用runtime_procUnpin解锁并重新进行Store过程.
      如果原子操作函数返回了true,即typ == nil,那么存储typ以及data的指针.

    • 后面的每次Store调用都是直接替换掉data指针

  • Load函数检测typ的值,如果为nil或者正在进行首次调用Store则会返回nil.否则返回一个interface{}(实际存储的是ifaceWords值)

用例

  • 在MIT的课程中,我们设计的每一个Server都需要访问viewService来获得最新的Primary/Backup数据库服务器视图.
    这时候其实对这个View的操作就是周期写,不定时读.这时候就是一个使用Value的合适场景(也可以使用原子函数CompareAndSwapPointer).

  • Go官网上给出的例子

    type Map map[string]string
    var m Value
    m.Store(make(Map))
    var mu sync.Mutex // used only by writers
    // read function can be used to read the data without further synchronization
    read := func(key string) (val string) {
            m1 := m.Load().(Map)
            return m1[key]
    }
    // insert function can be used to update the data without further synchronization
    insert := func(key, val string) {
            mu.Lock() // synchronize with other potential writers
            defer mu.Unlock()
            m1 := m.Load().(Map) // load current value of the data structure
            m2 := make(Map)      // create a new value
            for k, v := range m1 {
                    m2[k] = v // copy all data from the current object to the new one
            }
            m2[key] = val // do the update that we need
            m.Store(m2)   // atomically replace the current object with the new one
            // At this point all new readers start working with the new version.
            // The old version will be garbage collected once the existing readers
            // (if any) are done with it.
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值