使用goroutine迭代会产生意想不到的结果

时间:2016-05-31 13:52:12

标签: loops go concurrency goroutine

我根据迭代变量i在goroutine中进行了一些条件检查,发现它给了我不期望的结果,我决定用一些简单的代码来确认它。

    for i := 1; i <= 5; i++ {
    wg.Add(1)
    fmt.Println(i)

    go func() {
        fmt.Println(i)
        wg.Done()
    }()


}
wg.Wait()

1
2
3
4
5
6
6
6
6
6

这是预期的行为吗?有人可以解释为什么6被打印5次,虽然我只是迭代到5 ??

1 个答案:

答案 0 :(得分:5)

Playground example

你的for循环完成后,你所有的goroutine都在异步

在你的for循环结束时i等于6,因此,你的goroutines每个都记录数字6。

要解决此问题,您可以创建一个闭包,并在其中保存i的当前值,以便在goroutine运行时,它以i的正确值运行。

要执行此操作,只需更改代码,使其看起来像

go func(x int) {
  fmt.Println(x)
  wg.Done()
}(i) // <--- "save" value of i at this point in time.

这样你就可以节省&#34;你在函数中告诉goroutine执行的函数i的值,以后,当for循环运行完成时,它不会使用当前i为6;相反,它在创建goroutine时使用i值。