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,mutexLocked) 

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

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

解决方法

Go 没有 volatile 等价物。原子内存模型在 Go 中没有很好的定义,所以为了超级安全,你应该什么都不做,即对 a 的更改是不可见的。但实际上,据我所知,所有架构都会设置内存栅栏,因此您很安全。

有一个关于定义行为的 big issue,有一个 comment from Russ Cox 的说法

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

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