[转帖]go的调度机制.
调度器
主要基于三个基本对象上,G,M,P(定义在源码的src/runtime/runtime.h文件中)
- G代表一个goroutine对象,每次go调用的时候,都会创建一个G对象
- M代表一个线程,每次创建一个M的时候,都会有一个底层线程创建;所有的G任务,最终还是在M上执行
- P代表一个处理器,每一个运行的M都必须绑定一个P,就像线程必须在么一个CPU核上执行一样
P的个数就是GOMAXPROCS(最大256),启动时固定的,一般不修改;
M的个数和P的个数不一定一样多(会有休眠的M或者不需要太多的M)(最大10000);每一个P保存着本地G任务队列,也有一个全局G任务队列;
如下图所示

全局G任务队列会和各个本地G任务队列按照一定的策略互相交换(满了,则把本地队列的一半送给全局队列)
P是用一个全局数组(255)来保存的,并且维护着一个全局的P空闲链表
每次go调用的时候,都会:
- 创建一个G对象,加入到本地队列或者全局队列
- 如果还有空闲的P,则创建一个M
- M会启动一个底层线程,循环执行能找到的G任务
- G任务的执行顺序是,先从本地队列找,本地没有则从全局队列找(一次性转移(全局G个数/P个数)个,再去其它P中找(一次性转移一半),
- 以上的G任务执行是按照队列顺序(也就是go调用的顺序)执行的。(这个地方是不是觉得很奇怪??)
对于上面的第2-3步,创建一个M,其过程:
- 先找到一个空闲的P,如果没有则直接返回,(哈哈,这个地方就保证了进程不会占用超过自己设定的cpu个数)
- 调用系统api创建线程,不同的操作系统,调用不一样,其实就是和c语言创建过程是一致的,(windows用的是CreateThread,linux用的是clone系统调用)
- 然后创建的这个线程里面才是真正做事的,循环执行G任务
那就会有个问题,如果一个系统调用或者G任务执行太长,他就会一直占用这个线程,由于本地队列的G任务是顺序执行的,其它G任务就会阻塞了,怎样中止长任务的呢?
这样滴,启动的时候,会专门创建一个线程sysmon,用来监控和管理,在内部是一个循环:
- 记录所有P的G任务计数schedtick,(schedtick会在每执行一个G任务后递增)
- 如果检查到 schedtick一直没有递增,说明这个P一直在执行同一个G任务,如果超过一定的时间(10ms),就在这个G任务的栈信息里面加一个标记
- 然后这个G任务在执行的时候,如果遇到非内联函数调用,就会检查一次这个标记,然后中断自己,把自己加到队列末尾,执行下一个G
- 如果没有遇到非内联函数(有时候正常的小函数会被优化成内联函数)调用的话,那就惨了,会一直执行这个G任务,直到它自己结束;如果是个死循环,并且GOMAXPROCS=1的话,恭喜你,夯住了!亲测,的确如此
对于一个G任务,中断后的恢复过程:
- 中断的时候将寄存器里的栈信息,保存到自己的G对象里面
- 当再次轮到自己执行时,将自己保存的栈信息复制到寄存器里面,这样就接着上次之后运行了。
但是还有一个问题,就是系统启动的过程
- 系统启动的时候,首先跑的是主线程,那第一个M应该就是主线程吧(按照C语言的理解,嘿嘿),这里叫M1,可以看前面的图
- 然后这个主线程会绑定第一个P1
- 咱们写的main函数,其实是作为一个goroutine来执行的
- 也就是第一个P1就有了一个G1任务,然后第一个M1就执行这个G1任务(也就是main函数),创建这个G1的时候不用创建M了,因为已经有了M1
- 这个main函数里面所有的goroutine,都绑定到当前的M1所对应的P1上
- 然后创建main里的goroutine的时候(比如G2),就会创建新的M2,新的M2里的初始P2的本地任务队列是空的,会从P1里面取一些过来,哈哈
- 这样两个M1,M2各自执行自己的G任务,再依次往复,这下就圆满了
综上:
所以goroutine是按照抢占式调度的,一个goroutine最多执行10ms就会换作下一个
这个和目前主流系统的的cpu调度类似(按照时间分片)
windows:20ms
linux:5ms-800ms
注意:
在Golang中编译器也会尝试进行内联,将小函数直接复制并编译,为了内联,尽量消除编译器无法侦测的dead code,利用gobuild -gcflags=-m编译命令可以查看程序内联状态,不得不说golang的编译工具链还是很强大的,十分有利于程序的优化。
[转帖]go的调度机制.的更多相关文章
- (笔记)Linux内核学习(十一)之I/O层和I/O调度机制
一 块I/O基本概念 字符设备:按照字符流的方式被有序访问的设备.如串口.键盘等. 块设备:系统中不能随机(不需要按顺序)访问固定大小的数据片(chunk 块)的设备. 如:硬盘.软盘.CD-ROM驱 ...
- quartz集群调度机制调研及源码分析---转载
quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...
- 定时组件quartz系列<三>quartz调度机制调研及源码分析
quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...
- (1)quartz集群调度机制调研及源码分析---转载
quartz2.2.1集群调度机制调研及源码分析 原文地址:http://demo.netfoucs.com/gklifg/article/details/27090179 引言quartz集群架构调 ...
- quartz群调查调度机制和源代码分析
pageId=85056282#quartz集群调度机制调研及源代码分析-quartz2.2.1集群调度机制调研及源代码分析" style="color:rgb(59,115,17 ...
- Linux进程组调度机制分析【转】
转自:http://oenhan.com/task-group-sched 又碰到一个神奇的进程调度问题,在系统重启过程中,发现系统挂住了,过了30s后才重新复位,真正系统复位的原因是硬件看门狗重启的 ...
- [k8s]k8s的控制层kubelet+docker配合调度机制(k8架构)
意外停掉一台node的kubelet,发现调度有问题,研究了下调度的细节 k8s架构 控制层- kubelet(配合节点docker工作) 数据层- kube-proxy 逻辑图: object 参考 ...
- Golang 的 协程调度机制 与 GOMAXPROCS 性能调优
作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...
- [转]golang的goroutine调度机制
golang的goroutine调度机制 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 一直对goroutine的调度机制很好奇最近在看雨痕的golang源码分析基于go ...
随机推荐
- 【转载】基于MFC的ActiveX控件开发(1)
原文:http://iysm.net/?p=114 ActiveX 控件是基于组件对象模型 (COM) 的可重用软件组件,广泛应用于桌面及Web应用中.在VC下ActiveX控件的开发可以分为三种,一 ...
- 游戏手柄(JoyStick)编程学习笔记(2)
在我的上一篇博客中(http://blog.csdn.net/liyuanbhu/article/details/51714045),介绍了通过 multimedia joystick API 来访问 ...
- 【JLOI2013】卡牌游戏
题面 题解 概率$dp$ 设$f[i][j]$表示还剩$i$个人时,第$j$个人获胜的概率. 边界$f[1][1] = 1$ 转移: 枚举庄家抽到的卡牌$k$,得到这一轮被淘汰的位置$c$. 可以知道 ...
- REST API 开发
本文我们将使用Spring MVC 4实现 CRUD Restful WebService , 通过RestTemplate写一个 REST 客户端,定义这些服务. 我们也可以通过外部的一些客户端来测 ...
- 动态加载与插件系统的初步实现(四):解析JSON、扩展Fiddler
按文章结构,这部分应该给出WCFRest项目示例,我想WinForm示例足够详尽了,况且WCFRest还不需要使用插件AppDomain那一套,于是把最近写的Fiddler扩展搬上来吧. Fiddle ...
- ASP.NET MVC - PageData的应用
一.要实现一个功能,在不同的页面放置一段如下的内容,用于采集用户行为信息: <input type='hidden' id='page_id' value='xxxx' /> <sc ...
- Mysql优化之索引
前言 这几天抽了个时间将<高性能Mysql>看了一下忽觉索引非常之重要,习之然后总结巩固知识.本文索引使用的是InnoDB存储引擎.因为本文并不是说用索引的好处,所以并不会书写QPS之类的 ...
- 快手hr面
快手hr面 20180918 自我介绍 hr部门介绍 效率工程 主要问题 问我对部门是否有感兴趣? 我要求地点在北京,然后就畅聊口音.老家,学校等 学校的成绩?(研究生.本科) 自己属于哪类学生?(属 ...
- ETSI公布的多接入移动边缘计算概念验证
ETSI多接入移动边缘计算 公布的概念验证如下: 来源 MEC PoC Projects PoC#1: "Video User Experience Optimization via MEC ...
- CHAPTER 24 History of Our Planet 第24章 我们行星的历史
CHAPTER 24 History of Our Planet 第24章 我们行星的历史 Uncovering the bones of ancient beasts is only part of ...