• 【golang】调度系统之整体介绍


    调度系列
    调度系列之goroutine
    调度系列之m
    调度系列之p
    调度系列之sysmon

    前面几篇对调度体系的G、M、P、sysmon分别进行了介绍。拆分的介绍有助于聚焦单一的角色,比较快地建立认识,同时也能更深入细节,但是不足以建立全局的认知。本篇在前面几篇的基础上,进行汇总的介绍。介绍的方式为选取runtime的几个阶段,介绍调度体系在对应阶段的状态,以及阶段之间的演进。

    阶段1

    在此阶段,runtime已经初始化,系统中存在4个p。系统的负载很低,目前只有3个goroutine,p0、p1、p2被M占据并运行goroutine,p3处于idle状态。

    阶段2

    此时系统的负载仍然很低,没有新的goroutine创建。

    • p2上运行的goroutine结束后,对应的M进入schedule中,尝试从本地就绪队列、全局就绪队列、netpoll或者runnable的goroutine。
    • 获取不到后M进入spinning状态,尝试从其他的P中获取runnable的goroutine(steal work)。steal work会尝试4次,每次随机选择一个P进行。
    • M的spinning是一个非常短暂存在的状态。

    阶段3

    在阶段2中,占据p2的M处于spinning状态。但此时的系统中显然没有goroutine供其运行。处于spinning状态的M在获取不到goroutine后会释放占据的p,将其置为idle状态,然后将自己挂起,置于midle队列的头部。

    阶段4

    此时系统的负载上升,我们的生产应用绝大部分时间都处于该状态。

    • 每个p的本地就绪队列以及全局的就绪队列中都有goroutine等待调度。p1、p2、p3处于running状态。
    • p0上运行的goroutine在执行系统调用,处于syscall状态,此时M占据p进行系统调用。
    • 另外还有M没有占据p进行系统调用,这可能是被sysmon检测到执行时间过久进行的解绑,也有可能是在系统调用之初主动handoffp。
    • 也有一些goroutine处于阻塞队列中。

    阶段5

    • 此时p0由syscall转变为running状态;
      • 可能是因为系统调用结束,M主动将p0状态由syscall -> running;
      • 也可能是p0处于syscall状态的时间过长(超过10ms),被sysmon进行解绑。
    • 处于syscall状态的g对应的M在系统系统调用结束后会重新尝试获取P,如果获取不到,则g挂载在全局就绪队列中,M挂载到midle中。
    • 另外和goroutine绑定的M在goroutine被调度时也会挂载到midle中。

    以上为调度系统的整体的介绍。


    如果觉得本文对您有帮助,可以请博主喝杯咖啡~

  • 相关阅读:
    Tools-反射
    【Django】执行查询——比较、删除、复制、批量修改对象
    8月AI实战:工业视觉缺陷检测
    个人微信聚合管理怎么实现,和多开有什么不同?
    视频监控管理平台/视频汇聚/视频云存储EasyCVR安全检查的相关问题及解决方法3.0
    了解 Oracle 中的主键和外键
    从文件1到文件2传输内容
    小黑昨晚又内耗了起床来个leetcode:109. 有序链表转换二叉搜索树
    谷歌护眼插件Dark Reader下载安装使用
    dhrystone和coremark测试比较
  • 原文地址:https://blog.csdn.net/shanxiaoshuai/article/details/133419313