ove*_*nge 0 concurrency loops go goroutine
在下面的代码中:
package main
import "fmt"
func main() {
for i := 0; i <= 9; i++ {
go func() {
fmt.Println(i)
}()
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
code$
code$ go install github.com/myhub/cs61a
code$ bin/cs61a
code$
Run Code Online (Sandbox Code Playgroud)
以上程序不提供任何输出。
1)他们是否i在 10 个 go-routines 之间进行单一内存位置的数据竞争?
2)为什么上面的代码不打印自由变量的值i?
有数据竞赛吗?
是的,通过运行确认它go run -race example.go。主 goroutine 写入i,其他 goroutine 在没有任何同步的情况下读取它。请参阅将参数传递给函数闭包;为什么这两个 for 循环变体会给我不同的行为?并使用 range for loop slices/map 注册多个路由。
为什么上面的代码不打印任何东西?
因为当主 goroutine 结束时,你的程序也会结束。它不会等待其他非maingoroutine 完成。请参阅goroutine 无输出
复制循环变量,并在闭包中使用它,并使用 async.WaitGroup等待启动的 goroutines 结束:
var wg sync.WaitGroup
for i := 0; i <= 9; i++ {
i2 := i
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println(i2)
}()
}
wg.Wait()
Run Code Online (Sandbox Code Playgroud)
这将输出(在Go Playground上尝试):
9
0
2
1
6
5
3
7
8
4
Run Code Online (Sandbox Code Playgroud)
另一种方法是i作为参数传递给启动的函数:
var wg sync.WaitGroup
for i := 0; i <= 9; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Println(i)
}(i)
}
wg.Wait()
Run Code Online (Sandbox Code Playgroud)
在Go Playground上试试这个。