刚刚接触go语言,对于其内存模型不是很理解。能够明白通道通信,锁等内容。。但是对于最后的几个错误同步的例子不明白为什么?
例如:
var a string
var done bool
func setup() {
a = "hello, world"
done = true
}
func main() {
go setup()
for !done {
}
print(a)
}
和前面一样,这里不保证在 main 中对 done 的写入的监测, 蕴含对 a 的写入也进行监测,因此该程序也可能会打印出一个空字符串。 更糟的是,由于在两个线程之间没有同步事件,因此无法保证对 done 的写入总能被 main 监测到。main 中的循环不保证一定能结束。
上面这段说明中说有可能会出问题,打印空字符之类的,但是我没想白,不是只有等done为true之后才会进行print嘛,那时候不是已经进行赋值了嘛? 另外用go1.11 尝试运行多次,结果也是可以输出hello world的
还有<a href="/user/mlkr" title="@mlkr">@mlkr</a> 13楼说的可能是对的,cpu可能会乱序执行,这里应该保护一下
for循环这样的写法类似内核态里的自旋锁,用户态不建议这么写,会空耗大量cpu(新版的go是不是已经会对执行中的for进行调度了?)
#15
更多评论
好像不关内存什么事吧,是你基础没有学好
首先 done 的初始化应该为 false 就是 0,一般情况下 所有的语言 bool 类型 初始化都为 false
然后 for 循环,!done ,差不多相当于 只要是 done 为false 就会一直循环下去,直到 done 变为 true。
也就是 不关 你的 setup 什么时候执行,一旦执行后,done 变为 true,for 循环结束跳出,之后 print
#1