golang调度过程
2021-12-17 14:52:00 0 举报
golang调度过程
作者其他创作
大纲/内容
调度
N
调度初始化
初始化g0
返回g
如果P本地队列已满?
负载均衡
Y
执行findrunnable(),获取1个G
关联g0和m0
M把运行栈从g0切换到g
从全局队列拿一半放入本地队列,返回1个G
最大化并行
是否需要扩容P列表
runtime·rt0_go(SB)
复用或创建G:newg
M绑定P
设置goexitnewg.sched.pc = funcPC(goexit)
G存入可运行队列
退出
M执行G
启动m0
M执行锁定的G
为G分配id
通过g0绑定G和M
触发新一轮调度
如果next为真?
唤醒M/新创建M
是否需要缩容P列表
P绑定M
开始
如果M已经被某个G锁定
G退出
选出P本地队列前面的一半G
schedule()
返回可用的P
初始化P
P解绑M
G状态更新为_Grunning
等待GC完成被唤醒
触发调度
创建G
gcstopm()停止M
M获取G
清空g的信息
从P2中偷一半放入P的本地队列
set为空闲的P
把G加入P的本地队列
M切换为g0
M设置G运行环境
M被唤醒启动
设置P的最大数量:GOMAXPROCS
如果GC处于等待状态
取消M和G的关联
初始化P列表
执行
被释放P的所有G加入全局队列
加入到全局队列的尾部
初始化m0
随机选一个P:P2
M释放当前P
打乱顺序
调度器主线
进行各类的初始化:stack、malloc、mcommon、cpu、alg、modules、gc
procresize(nprocs int32) *p
调整P列表
runtime·gogo(SB)
M休眠
加入到P的本地队列
从P本地队列获取1个G
wakep()
是否有自旋/空闲的M
G放入P的free g列表
创建main函数的goroutine
设置M的最大数量:10000
P每执行61次调度,从全局队列中获取1个G(本地队列无g,拿一半放入本地队列)
存在空闲的P
关联P和当前M
Goexit()
函数和参数入G的栈:fn,args
G和P.runnext进行替换
schedinit()
运行g
申请新空间并copy旧列表
执行当前G的defer
收藏
0 条评论
回复 删除
下一页