Golang 官网一段关于同步错误的代码示例:
var a string
var done bool
func setup() {
a = "hello, world"
done = true
}
func main() {
go setup()
for !done {
}
print(a)
}
官网对这段代码的解析原文:As before, there is no guarantee that, in main, observing the write to done implies observing the write to a, so this program could print an empty string too. Worse, there is no guarantee that the write to done will ever be observed by main, since there are no synchronization events between the two threads. The loop in main is not guaranteed to finish.
print(a)
可能会输出一个空字符串这个比较好理解,因为 CPU 指令重排的原因,done = true
有可能先于a = "hello world"
语句执行,所以出现了这种情况。
但是 for 语句有可能会陷入死循环的原因我理解不了,原因是什么?
我猜测的原因是(有可能不正确):
done = true
的修改 CPU 只写入到了本地核心的 store buffer ,没有同步给其它 CPU 核心,导致不同核心的缓存数据不一致,接而导致运行在其它核心的 main 协程看不到这个修改,所以陷入了死循环
希望有大神能解析下原因,谢谢~
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.