
Go 调度
GMP 状态流转
G

- Gidle:G 被创建但还未完全被初始化。
- Grunnable:当前 G 为可运行的,正在等待被运行。
- Grunning:当前 G 正在被运行。
- Gsyscall:当前 G 正在被系统调用
- Gwaiting:当前 G 正在因某个原因而等待
- Gdead:当前 G 完成了运行
P

- Pidel:当前 P 未和任何 M 关联
- Prunning:当前P已经和某个 M 关联,M 在执行某个 G
- Psyscall:当前P中的被运行的那个 G 正在进行系统调用
- Pgcstop:runtime 正在进行 GC(runtime 会在 gc 时试图把全局 P 列表中的 P 都处于此种状态)
- Pdead:当前 P 已经不再被使用(在调用 runtime.GOMAXPROCS 减少 P 的数量时,多余的 P 就处于此状态)
M

调度
协作式调度
主动用户让权:runtime.Gosched()
Gosched 是一种主动放弃执行的手段,用户态代码通过调用此接口来出让执行机会,使其他人也能在密集的执行过程中获得被调度的机会。
抢占式调度
需要用户代码来主动配合的调度方式存在 一些致命的缺陷:一个没有主动放弃执行权、且不参与任何函数调用的函数,直到执行完毕之前, 是不会被抢占的。由于运行时无法 停止该用户代码,则当需要进行垃圾回收时,无法及时进行;对于一些实时性要求较高的用户态 Goroutine 而言,也久久得不到调度。
异步抢占式调度(10 ms)
- 抢占阻塞在系统调用上的 P
- 抢占运行时间过长的 G
安全点
- 栈扫描
- GC