当 P 的数量为 1 时 GMP 调度的问题

2022-05-10 14:13:02 +08:00
 AlpacaCode
```go
package main

import (
"fmt"
"runtime"
"sync"
)

func main() {
//
wait := sync.WaitGroup{}
runtime.GOMAXPROCS(1)
wait.Add(20)
str := "ABCDEFGHIJKLM"

for i := 0; i < 10; i++ {
go func(i int) {
fmt.Println(i, "---")
wait.Done()
}(i)
}

for i, l := 0, len(str); i < l; i++ {
go func(i int) {
fmt.Println(string(str[i]))
wait.Done()
}(i)
}
fmt.Println("---------------")
wait.Wait()
}

```
为什么这个程序会优先执行下面这个 goroutine 中的最后一个,然后再回到上面去执行
输出结果如下
```
---------------
M
0 ---
1 ---
2 ---
3 ---
4 ---
5 ---
6 ---
7 ---
8 ---
9 ---
A
B
C
D
E
F
G
H
I
```
如果从 GMP 的角度去看的话,一开始设置了 P 的数量为 1 那后续 G0 调用玩 goroutine 之后,把后续的 G 都塞到了本地 p 的队列里面 m 从里面取 输出的结果不应该是顺序的嘛, 为什么会产生单独输出一次 M 的现象

我所认为的理想状态下输出的内容
```
0123456789ABCDEFGHIM
```
1390 次点击
所在节点    Go 编程语言
6 条回复
hosora
2022-05-10 15:41:53 +08:00
因为 p 还有个 run_next
sardina
2022-05-10 15:57:44 +08:00
tobeagoodfather
2022-05-10 21:00:32 +08:00
@hosora
正解
vxyun
2022-05-11 00:09:21 +08:00

每次创建 goruntine 时,都会把当前 p 的 runnext 设置为 newg
AlpacaCode
2022-05-11 13:46:13 +08:00
@sardina 这是啥意思,进去只有一个 helloworld
AlpacaCode
2022-05-11 14:12:21 +08:00
@vxyun 我去,没想到队列 p 上面还有个 run_next, 看懂了谢谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/851973

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX