请教一下两个for内两个协程的执行顺序及结果的原因?
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
runtime.GOMAXPROCS(1)
wg := sync.WaitGroup{}
wg.Add(20)
for i := 0; i < 10; i++ {
go func() {
fmt.Println("i1: ", i)
wg.Done()
}()
}
for i := 0; i < 10; i++ {
go func(i int) {
fmt.Println("i2: ", i)
wg.Done()
}(i)
}
wg.Wait()
}
结果
i2: 9
i1: 10
i1: 10
i1: 10
i1: 10
i1: 10
i1: 10
i1: 10
i1: 10
i1: 10
i1: 10
i2: 0
i2: 1
i2: 2
i2: 3
i2: 4
i2: 5
i2: 6
i2: 7
i2: 8
关于执行顺序这个问题可以网上找一下详细的 Go 协程的设计模型—— GMP(Goroutine, Machine, Processer) 模型
然后简单回答一下楼主当前的疑惑,通过代码可知:
runtime.GOMAXPROCS(1)
设置了 P 只有一个,即程序只能运行一个 协程(Goroutine)main
被挂载在这个唯一 P 中,wg.Wait()
时,主协程让出,开始执行 P 的队列中的 Goroutine,即,runnext,和 FIFO 的队列结果原因:为什么两个 for 一边全是 10,而一遍是 0,1,2…
因为:创建协程的时候,变量在协程中的地址在第一个全是 for 的循环中是同一个,而这个值在 for 的执行过程中被修改为了 10. 而第二个 for 循环创建的协程中打印的这个变量是通过值传递传递的,则每个协程中的这个 i 的地址都是全新的,不一样的,即值是不一的