• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
古加纳
博客园    首页    新随笔    联系   管理    订阅  订阅

谈谈你对 Golang 调度模型的理解?

什么是golang调度模型:

golang调度模型即两级线程模型,是由G(goroutine)P(资源)M(工作线程,KSE绑定)三元素构成。M个G对N个M

设计策略:

复用线程 利用并行  抢占  全局G队列

work stealing机制 hand off机制

调度流程:(调度器模型图)

  每个M都包含一个g0(系统栈)和g(信号栈),这些称为系统g,M上其他的G则称为用户G。(go的角度)一个go func()创建,会首先加入P的本地可运行队列,P的可运行队列满了,就会导致P的本地队列的前半部分打乱顺序和先创建的G一起放入调度器的可运行队列。被M拿到后开始执行,销毁,然后开启新一轮调度帮助M获取其他的G。(如果此时G发生systemCall阻塞,此时M会锁定G,与当前的P解绑,唤醒或创建一个新的M,来绑定当前的P。等到这个G从系统调用退出时,判断是否可执行,可以继续执行,不行就放到调度器的可执行队列中)

(全局的角度)(一系列初始化完成后,会开启第一轮调度,此时会首先执行含有main函数的go代码,然后就会到go的创建一系列流程。schedule()函数会先从M开始,1 如果发现当前M已经与G锁定,此时检测G的状态,不可运行就停止此轮调度,可运行就执行这个G 2 没有绑定G,检查是否执行串行运行时任务(垃圾回收中的子任务,panic任务),没有则继续 。检查是否存在执行追踪读取任务的G;检查是否有执行GC标记任务的G;检查计数器是否为61的倍数,是的话在调度器的G可运行队列获取;检查P的本地G可运行队列中是否有可运行的G,没有就会进行阻塞,执行findrunnable()方法;

全力查找可运行G详细分为2个阶段10个步骤

1 是否可以在执行终结器获取G 2是否可以在本地可运行队列获取G 3是否在全局G可运行队列获取G  4I/O轮训器中获取G 5 去其他P偷取 6 检查是否有GC标记的G 78910

调度场景:

创建一个M

结束一个go

 

解决了什么问题

栈管理和抢占

 

快,滋醒这个做梦的人,有糖尿病的往后靠靠哈,不要给他点甜头!
posted @ 2021-04-13 17:33  古加纳  阅读(220)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3