Go gmp调度模型

协程调度模型:协程是轻量的线程,在线程基础上,没有上下文切换,无锁,效率高;协程有自己的调度模型,即gmp模型;

g:代表go关键字开的协程;

p:逻辑处理器,绑定一个m处理g;包括上下文信息,维护了自己需要调度的g的局部队列,一个go新建优先放入局部队列,局部队列小于256,超过拿一半放入全局队列;由GOMAXPROCS设置个数;

m:对应一个系统线程,内核态;m绑定p处理局部go队列,如果没有从全局队列拿一批,若全局队列没有,从其他p局部队列偷一半(即m空闲时,会从其他队列偷取,不会直接销毁线程)

用go关键字新建一个goroutine发生的调度过程:

1.把goroutine放入本地队列,本地满放入全局队列;

2.m绑定p执行g,优先本地队列获取,本地没有去全局队列获取,全局队列没有,去其他p的局部队列获取;

3.m执行g,若g因系统调用或其他原因阻塞,将m和p接触绑定,把p转到其他空闲(这个空闲的m可能来自于m之前阻塞挂起一段时间后返回的m)或新建(这个新建会导致m的数量大于p的数量,即,m和p数量上不上相等的)的m上执行;

4.执行完销毁g,从p的局部(本地)队列循环获取g执行;

notice:

1.m的数量限制最大10000,由SetMaxThreads设置,有m阻塞会新建一个,有m空闲会回收或睡眠;

2.go运行时间过长,会有sysmon监控,它会对schedtick增长计数,即每执行完一个g后递增(栈增长),如果长时间没有增长,说明执行同一个任务g,当超过10ms会在栈信息添加标记,之后执行在遇到非内联函数调用,会中断自己,加入队列尾;当没有遇到非内联函数时,会一直执行;

go func(){

for{}

}

出现这种情况,同时p=1,会夯住;在1.14版本后采用了基于信号的抢占式调度进行了优化;

3.g的中断恢复,中断时把寄存器中的栈信息保存到自己的g对象里,再次执行把栈信息复制到寄存器,继续上次后执行;

内存模型:

自己做图是不可能的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值