2016-05-31 65 views
0

我在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

另请参阅常见问题解答:https://golang.org/doc/faq#closures_and_goroutines – JimB

+0

也许更确切的重复:http://stackoverflow.com/questions/36776315/go-concurrency-with-for-loop-和 - 匿名函数 - 意外地行为 – JimB

+0

没有必要只有6,6,6,6。增加我的价值。你会得到不同的价值。您在执行goroutine时获得了i的价值。 – khrm

回答

5

Playground example

所有你够程都你的for循环结束后异步运行

在你的for循环i到底是等于6,因此,你够程每个日志数6

要解决,你可以创建一个封闭的问题,里面保存的i当前值这样当goroutine运行时,它将以适当的值i运行。

要做到这一点只是改变你的代码,以便它看起来像

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

这样,你的“保存”的i函数内部的价值你告诉够程来执行,使得以后,当为循环已经运行完成,它不使用当前的i这是6;相反,它在创建goroutine时使用旧的i

相关问题