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