GO GMP
M
指machine
,一个M
直接关联一个内核线程,有操作系统管理
P
值processor
,代表了M
所需要的上下文环境,也是处理用户级代码逻辑的处理器,负责衔接M
和G
的调度上下文,将等待执行的G
与M
对接。一般来说,P
的数量由环境变量中GOMAXPROCS
决定,通常与核心数对应
G
就是goroutine
,包括了调用栈,重要的调度信息,如channel等
一个M
会对应一个内核线程,一个M也会链接一个上下文P
,一个上下文P
又会连接一个或者多个G
形成runqueues。通过关键字go
启动一个G
加入runqueues队列末尾,一旦上下文运行到调度点,Goroutine
会从runqueues弹出,设置堆栈和指令指针开始运行Goroutine
如果M0
遇到一个syscall内核线程阻塞,这时候M0
会放弃当前的上下文环境P0
,P0
会被其它M
(新创建或者线程缓存)接受,以便让P0
下面的Goroutine
能被调度执行。而当M0
syscall结束后,会尝试去偷一个上下文P
,如果不成功,会把先面刚刚执行的G
放到全局的Goroutine
然后自己置于线程缓存中进入休眠状态。
P会周期性检查全局的runqueues队列里面的Goroutine
,以便在消费自身Goroutine
队列后继续执行全局runqueues,如果全局也没有了,P在跑完自己runqueues之后,会去其它的P
中偷一半过来