最近,我发现一些代码看起来像这样:
var m map[int]int
func writem() {
tmpm := make(map[int]int)
for i := 0; i < 4000000; i++ {
tmpm[i] = i + 10
}
m = tmpm
}
func readm() {
for k, v := range m {
_, _ = k, v
}
}
func main() {
writem()
go readm()
writem()
}
这个程序运行良好,但我认为writem
函数体可以通过m = tmpm
在 for 循环之前移动来重新排序,因为这不会改变这个 goroutine 中的行为。而这种重新排序将导致concurrent map read and map write
问题。正如Go 内存模型所说:
只有当重新排序不会改变语言规范所定义的 goroutine 中的行为时,编译器和处理器才可以重新排序在单个 goroutine 中执行的读取和写入
我是对的,还是这样写代码是安全的?