【发布时间】:2019-03-09 10:50:49
【问题描述】:
最近,我发现一些代码看起来像这样:
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 函数体可以通过在 for 循环之前移动 m = tmpm 来重新排序,因为这不会改变这个 goroutine 中的行为。而这种重新排序将导致concurrent map read and map write 问题。正如Go Memory Model 所说:
编译器和处理器可以重新排序在单个 goroutine 中执行的读取和写入,仅当重新排序不会改变语言规范所定义的 goroutine 内的行为时
我是对的,还是这样写代码是安全的?
【问题讨论】:
-
您引用的那句话不适用于您的情况,因为读取和写入 not 在同一个 goroutine 中。所以我不太明白你的问题。
标签: go concurrency happens-before data-race