Scalable Go Scheduler Design Doc, Dmitry Vyukov, May 2, 2012
系统调用/ M停车和取消停车
当M创建新的G时,必须确保还有另一个M 执行G(如果不是所有M都已经忙)。同样,当M 进入syscall,它必须确保还有另一个M来执行Go 代码。
有两种选择,我们可以立即阻止和取消阻止M, 或进行一些旋转。这是性能之间的内在冲突 并消耗不必要的CPU周期。这个想法是使用旋转并做 消耗CPU周期。但是,它不应影响运行 GOMAXPROCS = 1(命令行实用程序,appengine等)。
旋转有两个级别:(1)空闲的M和关联的P旋转 寻找新的G,(2)没有关联的P旋转的M等待 可用的P。最多有GOMAXPROCS个旋转的M(两者(1)和 (2))。类型为(1)的闲置M不会被阻塞,而存在的闲置M是 输入(2)。
生成新的G或M进入系统调用或M从 闲到忙,它确保至少有1个旋转的M(或全部 P很忙)。 这可确保没有可运行的G 否则会运行;并避免在 在同一时间。
旋转通常是被动的(对OS产生的收益,sched_yield()),但可能 包括一点主动旋转(循环燃烧CPU)(要求 调查和调整)。
这确保没有可运行的G,否则 正在运行
If there was no such ensurence, there may be runnable G's that can be running.
如果句子的意思是,这是我的理解:
在设计文章中,如果goroutine是可运行的,它将在P的可运行goroutines列表(或globel列表)中,并等待P(处理器)将其调度为在M(机器)上运行。
要确保没有可运行的G可以正常运行,这意味着要确保go进程有效利用CPU资源,我们需要确保始终有足够的M(机器线程,又名OS线程)等待(旋转)绑定到具有可运行goroutine的非空列表且没有M尽快与其绑定的P(Processor)。
确保至少有1个旋转的M可以实现此目标。