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 还是没有就休眠

 

posted @ 2023-06-01 09:43  rudynan  阅读(24)  评论(0编辑  收藏  举报