首页 > 解决方案 > Go 中的原子操作是否确保其他变量对其他线程可见?

问题描述

这让我很困惑,我正在阅读 golang 内存模型,https: //golang.org/ref/mem

var l sync.Mutex
var a string

func f() {
    a = "hello, world"
    l.Unlock()
}

func main() {
    l.Lock()
    go f()
    l.Lock()
    print(a)
}

互斥锁通过原子解锁

UnLock: new := atomic.AddInt32(&m.state, -mutexLocked)

Lock: atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) 

我的问题是,如果原子 AddInt32,CompareAndSwapInt32 会导致内存障碍,如果a将在不同的 goroutine 中可见。

在java中,我知道AtomicInteger,“volatile”的内存屏障,保持线程字段可见。

标签: gomemory-barriersmemory-model

解决方案


Go 没有 volatile 等价物。原子内存模型在 Go 中没有得到很好的定义,所以为了超级安全,你不应该假设任何东西,即对 的更改a是不可见的。但在实践中,据我所知,所有架构都会做一个内存围栏,所以你很安全。

关于定义行为有一个大问题, Russ Cox 有评论

是的,我在去年冬天花了一段时间,但还没有机会把它写好。简短的版本是我相当确定规则将是 Go 的原子保证原子变量之间的顺序一致性(行为类似于 C/C++ 的 seqconst 原子),并且您不应该混合给定的原子和非原子访问记忆词。

相关答案https://stackoverflow.com/a/58892365/2133484


推荐阅读