golang的gmp面试一定面到,学到就是赚到。

基本概念

gmp名称很简单,goroutine是虚拟线程,machine是机器线程,processor是进程处理器。

goroutine其实就是嗷嗷待哺的task。processor分配,如何machine执行。

m到p是m:n的高端操作。

m其实会挂起,所以p才等于机器核数。

调度

一般跑队列都是那种汉堡王排队,排一个先进先出的队列,然后窗口空了,去点菜。

但是如果任务跑的够快,这样用户走过去就很慢,会一直跑锁。

所以调度器结合了麦当劳排队和漫展排队,一个processor维护了一个一批进队列,处理完了再进。

进队列可以从外面的锁进满,也可以从别的队列进它的一半的任务。

一个任务最多10ms,就切换,比较科学。

gmp组合系统调用的时候,gm和p会分家,p会找下一个m跑g,挂起的gm会在调用完成之后,g回到执行队列,m变成空闲,等着别的m阻塞了再出山。

运行的m小于p的时候,其他p-m个线程如果存在,就会自旋,到处找g跑,剩下的闲着就闲着了,反正就那么多p,努力也没用。

阻塞

I/O,select block on syscall channel 等待锁 runtime.Gosched()

生命周期

M0是第一个M,总得有个干活的。

G0是M上的第一个G,负责调度。

一个程序,会先初始化M0,然后是它的G0,然后初始化P,直接跑M0G0,然后是main