package main
import (
"fmt"
"runtime"
)
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
fmt.Println(runtime.GOMAXPROCS(0))
// s := "hello world \n"
for i := 0; i < 100; i++ {
go func(n int) {
fmt.Println(n, i)
}(i)
}
fmt.Scanln()
}
Run Code Online (Sandbox Code Playgroud)
我只是想知道为什么n不等于i每一个例程.
也i有时具有相同的值在上一次调用.
这段代码有什么问题?
这个主题很好地涵盖了(跨多种语言) - 但简短的版本是这样的:
您当前的输出是这样的:
1 100
2 100
3 100
4 100
...
Run Code Online (Sandbox Code Playgroud)
变量i成为闭包的一部分.这意味着它的值实际上超出了它的范围(它移到了一边,以便当goroutine执行时它知道在哪里找到i).
当调度程序开始执行你的goroutine时,for循环已经完成并且值i将为100(或者如果你在慢速机器上运行则接近它).
修复是每次迭代存储值并使用:
for i := 0; i < 100; i++ {
x := i // <------ Store the value of i each loop iteration
go func(n int) {
fmt.Println(n, x) // <---- Use the new, local, closed over value, not the main closed over one
}(i)
}
Run Code Online (Sandbox Code Playgroud)
现在每个goroutine引用它自己的一个闭合变量的副本x,你的输出变为:
1 1
2 2
3 3
4 4
...
Run Code Online (Sandbox Code Playgroud)
这种现象并不孤立于Go.
你可以在操场上看到一个工作样本: View it on the Playground
| 归档时间: |
|
| 查看次数: |
216 次 |
| 最近记录: |