go gmp
M G P
M:machine 系统线程,执行实体,通过系统调用clone来创建
G:groutine 任务和上下文
P: 虚拟处理器,M需要获得P才能执行否则休眠
go的调度本质上是一个生产消费的流程
生产端
M负责调度循环消费task
队列分runnext+本地队列+全局队列来区分优先级,也避免锁
本地队列使用的数据结构是数组,内存是连续的连续性好
全局队列使用的数据结构是链表,无需扩展
1. runnext为空
协程任务G会赋值给runnext
2. runnext不为空,local 队列不满
协程任务G会赋值给runnext,原本在runnext的task被踢出后放入本地队列
3. runnext不为空,local 队列满了
协程任务G会赋值给runnext,原本在runnext的G被踢出后 与local队列的一半G 放入全局队列
消费端
1. schdule会每执行60次去全局队列取G,如果队列有值schedule去执行代码
2. 如果全局队列为空或者%60 != 0,会去runnext+本地队列取
3. 如果runnext+本地队列没值,反复去本地-》全局队列取值
4. 如果没有值去netpoll取网络任务
5. 如果没有去其他的T取可执行任务
6. 如果没有执行休眠流程,检查所有的队列+netpoll 还是没有就休眠