Golang 如何并发共享变量
本次讨论的重点是理解 Go 中多个 goroutine 之间如何共享变量。考虑以下代码:
<code class="go">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") }</code>
执行后,获得预期输出:
4 0 1 3 2
但是当对代码进行细微修改时:
<code class="go">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") }</code>
结果输出出乎意料地一致:
5 5 5 5 5
解释
关键区别在于 Goroutine 中变量的作用域。
In在第一个代码片段中,循环的每次迭代都会创建一个新变量 x 并将其值传递给 goroutine。当 goroutine 执行时,它有 x 的本地副本并打印其初始值。这样就得到了预期的输出。
但是,在第二个代码片段中,所有 goroutine 共享一个变量 i。当 goroutine 执行时,它会在循环完成后检索 i 的最终值。因此,所有 goroutine 都输出相同的值,5。
影响和最佳实践
这种行为凸显了使用 goroutine 时变量范围的至关重要性。为了确保线程安全执行,必须考虑变量的范围并在必要时利用等待组等同步原语(如两个代码片段中所示)。
以上是为什么 Golang Goroutines 在共享变量时输出相同的值?的详细内容。更多信息请关注PHP中文网其他相关文章!