goroutine 排队、调度

有以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func question(cnt int) {
runtime.GOMAXPROCS(1)

var wg sync.WaitGroup

for i := 1; i <= cnt; i++ {
wg.Add(1)
go func(n int) {
defer wg.Done()
println(n)
}(i)
}

wg.Wait()
}

给出不同范围的cnt的输出是什么

cnt 小于等于 257 时,输出为序列

1
2
3
4
5
6
cnt
1
2
3
...
cnt-1

cnt 大于等于 258 时,输出为

1
2
3
4
5
6
7
8
9
10
cnt
*
...
1
*
...
*
...
2
...

首先,解释为什么第一个一般都是cnt, 在循环中cnt最后一个被加入到协程队列中,其实会被加到runnext中,在协程队列中第一个会执行runnext,然后会从本地runq中取协程,但是本地队列中一旦加入超过256个协程,就会切出128个到全局runq中,如此往复。同时每当本地runq执行了61次后就会从全局runq中获取一个进行执行,主要是防止全局runq中的协程被饿死。于是就会有如上输出。


goroutine 排队、调度
https://fatwang1.github.io/2024/06/26/2024062500/
作者
衣云乘风
发布于
2024年6月25日
许可协议