首页  >  文章  >  后端开发  >  为什么 Go 中的 Goroutines 在共享变量时打印不同的值?

为什么 Go 中的 Goroutines 在共享变量时打印不同的值?

Patricia Arquette
Patricia Arquette原创
2024-11-05 19:23:02653浏览

Why Do Goroutines Print Different Values When Sharing Variables in Go?

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(&amp;x)
        }()
    }
    wg.Wait()
    fmt.Println("Done")
}

运行此代码将为每个 goroutine 显示不同的内存地址。

在第二个片段中,变量 i 在传递给 go func() 的匿名函数中直接引用。这意味着所有 goroutine 共享相同的 i 值,这导致了统一的输出。

以上是为什么 Go 中的 Goroutines 在共享变量时打印不同的值?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn