GoLang 内存模型文档指出以下代码可能会导致 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)。 f() 函数修改这些变量,g() 函数随后打印它们的值。
在 goroutine 中,语言规范确保读取和写入按照程序指定的顺序发生。然而,操作的重新排序可能会在不影响 Goroutine 行为的情况下发生,这里就是这种情况。
在 f() Goroutine 中,编译器可以通过重新排序 b 和 a 的赋值来进行优化。由于 Goroutine 在赋值后不会使用这些变量,因此重新排序不会影响其行为。
另一方面,goroutine 之间的同步需要一致性。在同步点,编译器保证所有赋值都已完成,确保 g() goroutine 读取 a 和 b 时都已分配了值。这可确保正确打印修改后的值(2 和 1)。
以上是为什么 Go 的并发执行会导致意外的变量值?的详细内容。更多信息请关注PHP中文网其他相关文章!