Go Lang 中同步不正确
Go 内存模型文档解释了以下代码可能会导致 g 打印 2,然后0:
var a, b int
func f() {
a = 1
b = 2
}
func g() {
print(b)
print(a)
}
func main() {
go f()
g()
}
登录后复制
解释:
- 在任何函数执行之前,变量 a 和 b 被初始化为零值 (0)。
- Go 内存模型中的 Happens Before 规则允许编译器和处理器在单个 goroutine 中重新排序操作,如果重新排序不会影响其行为。
- 在 f() 函数中,如果重新排序不会在该 goroutine 中产生差异,则对 a 和 b 的赋值可能不会按指定顺序发生。
- 由于赋值对 f() 函数没有影响,出于效率原因,编译器可能会对它们重新排序。
- 由于两者之间没有同步在提供的示例中,goroutines(即 f() 和 g()),编译器不会尝试确保它们之间的一致性。
- 但是,如果您在 goroutine 之间引入同步,编译器将保证在同步点,两项分配都将“完成”。这意味着正确的值(2 和 1)将被打印在 g() 中。
以上是为什么 Go 的 `go f(); g()` 打印'20”而不是'21”?的详细内容。更多信息请关注PHP中文网其他相关文章!