Go 中的 Goroutine 共享变量行为
问题:
在探索 Go 的并发特性时,开发人员在 goroutine 之间共享变量时遇到意外行为。在某些代码修改的情况下,输出完全不同。
在下面的代码片段中,每个 goroutine 正确打印其相应的 x 值:
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) x := i go func() { defer wg.Done() fmt.Println(x) }() } wg.Wait() fmt.Println("Done") }
但是,对代码为所有 goroutine 生成统一的结果:
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() fmt.Println(i) }() } wg.Wait() fmt.Println("Done") }
答案:
在第一个片段中,每个 goroutine 都有变量 x 的新实例。这是因为 x := i 在每次循环迭代时都会创建一个新变量。
为了演示这一点,我们可以在每个 goroutine 中打印 x 的内存地址:
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) x := i go func() { defer wg.Done() fmt.Println(&x) }() } wg.Wait() fmt.Println("Done") }
运行此代码将为每个 goroutine 显示不同的内存地址。
在第二个片段中,变量 i 在传递给 go func() 的匿名函数中直接引用。这意味着所有 goroutine 共享相同的 i 值,这导致了统一的输出。
以上是为什么 Go 中的 Goroutines 在共享变量时打印不同的值?的详细内容。更多信息请关注PHP中文网其他相关文章!