如何理解Go内存模型中的“同步错误”样本

fly*_*ine 4 synchronization go

我刚刚开始学习 golang,在阅读Go 内存模型时,我遇到了一个问题来理解它所说的“另一个不正确的习惯用法是忙着等待一个值”,

var a string
var done bool
func setup() {
    a = "hello, world"
    done = true
}
func main() {
    go setup()
    for !done {
    }
    print(a)
}
Run Code Online (Sandbox Code Playgroud)

它说:

“更糟糕的是,不能保证 main 会观察到对 done 的写入,因为两个线程之间没有同步事件。不能保证 main 中的循环完成。”

我知道在 setup() 中写入“a”和“done”的顺序不是确定性的,我的问题是:为什么 main 不能保证看到写入完成?

谢谢

pet*_*rSO 5

package main

var a string

var done bool

func setup() {
    a = "hello, world"
    done = true
}
func main() {
    go setup()
    for !done {
    }
    println(a)
}
Run Code Online (Sandbox Code Playgroud)

你有两个 goroutine,main 和 setup。例如,假设它们在具有本地内存缓存的单独 CPU 上的单独线程上运行。假设 main 和 setup 都将 did 变量读入本地 CPU 内存缓存。setup Goroutine 更新在其本地内存缓存中完成,这会执行延迟写入。由于独立的 main 和 setup goroutine 之间没有缓存同步事件,因此无法保证缓存一致性,无法保证主内存和两个 CPU 内存缓存将同步。不同的硬件对此的处理方式不同。在Go中,只能保证最低公分母。

请参阅缓存一致性