首先抛出本文的结论:Go 调度的本质是一个生产-消费流程。这是参加曹春晖的Go训练营时,大佬给出的结论。

生产者-消费者

生产者-消费者模型

我们平时用 Go 最爽的一点莫过于用一句 go func(){}() 就启动了一个 goroutine 来并发地执行任务。这比用 C/C++ 启动一个线程并发地去执行任务方便太多。这句代码实际上就生产出了一个 goroutine,并进入可运行队列,等待和 m 来找它从而可以得到运行。

熟悉 GMP 模型的朋友都知道,goroutine 最终在 m 上得以执行,因为操作系统感知不到 goroutine,它只能感知线程,并且线程可以看成是 m。

所以,m 拿到 goroutine 并运行它的过程就是一个消费过程。

生产-消费过程

生产过程——三级队列

生产出的 goroutine 需要找一个地方存放,这个地方就是可运行队列。在 Go 程序中,可运行队列是分级的,分为三级:

三级可运行队列

runnext 实际上只能指向一个 goroutine,所以它是一个特殊的队列。

那把 goroutine 放到哪个可运行队列呢?看情况。

首先,如果 runnext 为空,那么 goroutine 就会顺利地放入 runnext,接下来,它会以最高优先级得到运行,即优先被消费。

如果 runnext 不为空,那就先负责把 runnext 上的 old goroutine 踢走,再把 new goroutine 放上来。具体踢到哪里呢?又得分情况。

local queue 是一个大小为 256 的数组,实际上用 head 和 tail 指针把它当成一个环形数组在使用。如果 local queue 不满,则将 runnext 放入 local queue;否则,P 的本地队列上的 goroutine 太多了,说明当前 P 的任务太重了,需要减负,因此需要得到其他 P 协助。从而,将 runnext 以及当前 P 的一半 goroutine 一起打包丢到 global queue 里去。

当然,这部分课程里有非常生动的动画,这里贴一个截图大家感受一下:

生产者动画

消费过程——调度循环

之前的文章里也讲到过调度循环是咋回事,它实际上就是 Go 程序在启动的时候,会创建和 CPU 核心数相等个数的 P,会创建初始的 m,称为 m0。这个 m0 会启动一个调度循环:不断地找 g,执行,再找 g……

伪代码是这样的:

调度循环

随着程序的运行,m 更多地被创建出来,因此会有更多的调度循环在执行。

那边生产者在不断地生产 g,这边 m 的调度循环不断地在消费 g,整个过程就 run 起来了。

找 g 的过程中当然也是从上面的三级队列里找:

先看 runnext,再看 local queue,再看 global queue。当然,如果实在找不到,就去其他 p 去偷。

总结

今天的文章只用记住一个观点:Go 调度的本质是一个生产-消费流程。这个观点非常新颖,之前我没有从哪篇文章看到过,这是曹大自己的感悟。


欢迎关注曹大的 TechPaper 以及码农桃花源~

用四张图说清楚Go程序调度的本质相关推荐

  1. 基于BLM业务领先模型演化的项目管理四张地图

    四张地图分别为业务地图.组织地图.能力地图和氛围地图,作为基层项目管理者通过梳理四张地图,并定期审视调整,即可带好项目组的同时,将各项工作连成一张皮.业务地图说核心,其他三张地图均围绕着业务地图展开, ...

  2. MySQL怎么运行的系列(八)14张图说明白MySQL事务原子性和undo日志原理

    本系列文章目录 展开/收起 MySQL怎么运行的系列(一)mysql体系结构和存储引擎 MySQL怎么运行的系列(二)Innodb缓冲池 buffer pool 和 改良版LRU算法 Mysql怎么运 ...

  3. 一句话+一张图说清楚——银行家算法

    本文试图用一句话+一张图说清楚操作系统中的银行家算法.我相信用一句话可以讲清楚一个算法的核心思想,一张图可以描述整个算法的操作步骤.但本人能力有限,错误之处望大家指出,多谢. 一句话: 当一个进程申请 ...

  4. Java黑皮书课后题第7章:*7.29(游戏:挑选四张牌)编写一个程序,从一副52张牌中选出4张,然后计算它们的和。Ace King Quee Jack分别表示1、13、12和11,显示得到和24的次

    *7.29(游戏:挑选四张牌)编写一个程序,从一副52张牌中选出4张,然后计算它们的和.Ace King Quee Jack分别表示1.13.12和11,显示得到和为24的选牌次数 题目 题目描述 破 ...

  5. Java黑皮书课后题第7章:**7.24(仿真:优惠券收集问题)优惠券收集问题是一个经典的统计问题。编写程序,模拟要得到四张不同花色的牌所需要的选取次数,然后显示选中的四张牌

    **7.24(仿真:优惠券收集问题)优惠券收集问题是一个经典的统计问题.编写程序,模拟要得到四张不同花色的牌所需要的选取次数,然后显示选中的四张牌 题目 题目描述与运行示例 破题:花色与数字 代码 题 ...

  6. oracle高级查询案例,oracle高级查询(实例基于scott用户四张表)

    oracle高级查询(实例基于scott用户四张表) 分组查询 多表查询 子查询 综合实例 ====================================================== ...

  7. 四张图带你了解Tomcat系统架构--让面试官颤抖的Tomcat回答系列

    转载自   四张图带你了解Tomcat系统架构--让面试官颤抖的Tomcat回答系列 俗话说,站在巨人的肩膀上看世界,一般学习的时候也是先总览一下整体,然后逐个部分个个击破,最后形成思路,了解具体细节 ...

  8. 【视觉项目】【day5】8.25号实验记录(修完BUG,28张测试图,13个样本,四张测试图误判,这比之前效果好很多了)

    目录 修改完BUG后的程序以及效果 优化思路,增强正确识别率(待验证) 修改完BUG后的程序以及效果 修改代码后的测试结果:(利用连通域面积将明显比本张测试图的瓶子要小的模板提前去除,减少误判) 这样 ...

  9. c mysql 统计不重复数据库,MySQL_MySQL数据库中分组统计的问题,首先准备四张表A、B、C、D, - phpStudy...

    MySQL数据库中分组统计的问题 首先准备四张表A.B.C.D, -------------------------------- A      | B | C   | D a   b   |   a ...

最新文章

  1. 第十、十一周项目一-点-圆-圆柱类族的设计(2)
  2. 大数据催生决策新模式 未来将改变更多
  3. [Python]再学 socket 之非阻塞 Server
  4. mysql 导出gbk_mysqldump指定编码导出数据,GBK编码实践
  5. 机器学习的核心工作流程
  6. 固定顶部指定div不滑动
  7. linux下执行scrapy的爬虫定时任务
  8. err2matlab,matlab中增量调制的编程问题
  9. 蓝桥杯 ALGO-160 算法训练 P0104
  10. 动易2007后台模板上传任意文件漏洞
  11. 论文公式以及公式标号怎么通过统一格式(居中、居右)
  12. 液晶手写板原理拆解_天猫babycare儿童液晶手写板详情页拆解
  13. 摄影欣赏:30幅五光十色的精美秋天风景摄影作品
  14. python最小二乘法_最小二乘法(least sqaure method)
  15. python如何返回一个列表_python如何返回元组,列表或字典的?
  16. spss pro网络挑战赛A题:人群疏散模拟代码
  17. hmailserver搭建一个公网可收发的自用邮局
  18. 添加myenv至jupyter notebook kerne
  19. 算法导论 — 思考题8-6 合并有序列表的下界
  20. 不要只怀揣梦想,而是要努力实现梦想!

热门文章

  1. 五周第二次课(4月19日)
  2. 【quickhybrid】API的分类:短期API、长期API
  3. vue2 枚举类型转换
  4. Python 学习笔记9(装饰器,decorator)
  5. jqGrid数据增删查改
  6. PHP 制作通讯录(六)
  7. sendmail for linux
  8. GDB 调试 Mysql 实战(一)源码编译安装
  9. Linux系统CentOS 7配置Spring Boot运行环境
  10. 编写第二个页面:新闻阅读列表页面