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