go中调度机制
G-M-P模型
G代表Goroutine即协程
M表示Machine即工作线程
P表示Processor即处理器
G-P-M关系
P中维护一个协程队列。除此之外还有一个全局的协程队列。
G会被放到P中的协程队列或者全局队列中
M必须要绑定一个P才能执行G
可以简单的理解为,P是一个资源池,用来存放G,M从P中取出G来执行。M可以理解成广义上的线程
P的数量一般是有GOMAXPROCS决定的,M的数量会略大于P的数量
调度过程:以创建新的G为例
创建G时,会先判断有没有空闲的P,有的话创建M绑定P,将新的G放到该P队列中。
如果没有空闲P,判断当前P队列是否满了,没满的话就放到P队列中,如果满了,会将P中的一半连同新的G一起放到全局队列中。
M周期性的从P中取出G来执行,并且定期从全局队列中取出G来执行,防止全局队列中的G被饿死。
当M因为当前G陷入系统调用或者阻塞时,M会记住当前的P,然后解绑P,P如果没有G了,就会进入空闲状态,
如果有G会从M缓存池取空闲的M或者创建一个M
来继续执行队列中的G。当M结束系统调用时,先找之前的P,没有找到会找到一个空闲的P,找到了就绑定P,将G放到P队列中,
继续执行
如果找不到的话,就将G放到全局队列中,陷入睡眠状态。
当P中的队列中不存在G,会从全局队列中取G来执行。如果全局队列也没有G。就从其他P中偷取,每次偷一半
每个M都有一个G0,用来在调度或者系统调用的时候使用其栈空间。
M0除了负责初始化操作和启动第一个G之后跟其他的M一样。
G执行完成后会切换为G0,然后G0负责调度协程切换
个人理解,如有错误,欢迎友好交流。
文章来源于互联网:go调度机制简介