一、GMP模型原理first:

1. 全局队列:存放待运行的G
2. P的本地队列:同全局队列类似,存放待运行的G,存储的数量有限:256个,
当创建新的G‘时,G’优先加入到P的本地队列,如果队列已满,会把P本地队列中一半的G移动到全局队列
3. M线程:M运行G需要先获取P,然后从P本地队列中取G运行,如果P本地队列为空,M会把全局队列中一批G移动到P本地队列
或去其它P队列中偷一半G到P本地队列,M运行G,G执行完后,M会从P获取下一个G,不断重复执行
4. P列表:所有的P都在程序启动时创建,并保存在数组中,最多有GOMAXPROCS个

总结:goroutine调度器与OS线程调度器通过M结合起来,每一个M代表一个内核线程,OS调度器负责把内核线程分配到CPU上去执行

second:
有关 P 和 M 的数量问题
1. P 的数量:
由程序启动时环境变量 $GOMAXPROCS 或 runtime方法GOMAXPROCS()决定,
这意味着在程序执行的任意时刻都只有 $MAXPROCS个goroutine在执行
2. M 的数量
2.1 go 语言本身的限制,go 程序启动时会设置M的最大数量,默认10000,但是内核很难支持这么多的线程,
所以可以忽略,
2.1 runtime/debug中的SetMaxThreads函数,设置 M 的最大数量
2.3 当一个M阻塞了,会创建新的M
3. M和P的数量没有绝对关系,一个M阻塞,P就会创建或者切换其它的M,所以即使P的数量是1,也有可能创建出很多个M出来

three:
P 和 M 何时会被创建
1. P 何时创建:在确定了P的最大数量n后,runtime运行时系统会根据这个数量创建n个P
2. M 何时创建:没有足够的M来关联P并运行其中可运行的G;比如此时所有的M都阻塞住了,
但是P中还有很多就绪任务,此时就会去创建新的M

二、调度器设计策略
 

1. 复用线程:避免重复的创建、销毁线程,而是对线程的复用
work stealing机制:当本线程M无可运行的G时,会尝试从其它线程绑定的P中偷取G,而不是销毁线程
hand off机制:当本线程M因为G进行系统调用时阻塞,线程M释放绑定的P,交给其它空闲的线程M去执行
利用并行:GOMAXPROCS设置P的数量,最多有GOMAXPROCS个线程分布在多个CPU上运行,
GOMAXPROCS也限制了并发的程度,当设置 GOMAXPROCS = CPU核数/2 时,则最多利用了一半的CPU核进行并行

2. 抢占:在coroutine中要等待一个协程让出CPU才执行下一个协程,而在go中,一个goroutine最多占用CPU 10ms,
防止其它goroutine被饿死,这就是goroutine不同于其它coroutine的区别

3. 全局G队列,在新的调度器中依然有全局G队列,但是功能被弱化了,当M执行 work stealing 从其它P队列偷不到G时,
它可以从全局G队列获取G
三、go func 调度流程

1. 我们通过 go func() 来创建一个 goroutine
2. 有两个存储G的队列,一个是局部调度器P的本地队列,一个是全局G队列,新创建的G会先保存在P的本地队列中
如果P的本地队列已满就会保存在全局队列中
3. G只能运行在M中,一个M必须持有一个P,M与P的关系时1:1,M先绑定P然后从P队列中弹出一个可运行的G并执行,
如果P本地队列为空,M会向其它MP组合偷取一个可运行的G运行
4. 一个M调度G执行的过程是一个循环机制
5. 当一个M执行一个G时发生了syscall或其它阻塞操作,M会阻塞,如果当前有一些G待执行,runtime会把这个线程M
从P中摘除,让其它空余的M线程(如果没有就创建新的M线程)来服务于这个P
6. 当M系统调用结束的时候,这个G会尝试获取一个空闲的P,并放入到P的本地队列中取,如果获取不到P,
这个M线程变成休眠状态,加入到空闲线程中去,然后这个G会被放入到全局队列中

四、调度器的声明周期

M0: 是启动程序后编号为0的主线程,M0负责初始化操作和执行第一个G,在之后M0就和其它M一样了
G0: 是每次启动M都会第一个创建的goroutine,GO仅用于负责调度的G,G0不指向任何可执行的函数,
每个M都会有一个自己的G0,在调度或系统调用时会使用G0的栈空间,

总结:go调度器的本质:把大量的goroutine分配到少量的线程上去执行,并利用多核并行,实现更强大的并发

参考链接:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/GMP%E5%8E%9F%E7%90%86%E4%B8%8E%E8%B0%83%E5%BA%A6.html

golang中GPM模型原理与调度器设计策略的更多相关文章

  1. golang中goroutine协程调度器设计策略

    goroutine与线程 /* goroutine与线程1. 可增长的栈os线程一般都有固定的栈内存,通常为2MB,一个goroutine的在其声明周期开始时只有很小的栈(2KB),goroutine ...

  2. 《k8s-1.13版本源码分析》- 调度器设计

    本文原始地址:https://farmer-hutao.github.io/k8s-source-code-analysis/core/scheduler/desigh.html github项目地址 ...

  3. Golang中的自动伸缩和自防御设计

    Raygun服务由许多活动组件构成,每个组件用于特定的任务.其中一个模块是用Golang编写的,负责对iOS崩溃报告进行处理.简而言之,它接受本机iOS崩溃报告,查找相关的dSYM文件,并生成开发者可 ...

  4. 【转】Go调度器原理浅析

    goroutine是golang的一大特色,或者可以说是最大的特色吧(据我了解),这篇文章主要翻译自Morsing的[这篇博客](http://morsmachine.dk/go-scheduler) ...

  5. Kubernetes集群调度器原理剖析及思考

    简述 云环境或者计算仓库级别(将整个数据中心当做单个计算池)的集群管理系统通常会定义出工作负载的规范,并使用调度器将工作负载放置到集群恰当的位置.好的调度器可以让集群的工作处理更高效,同时提高资源利用 ...

  6. kubernetes 调度器

    调度器 kube-scheduler 是 kubernetes 的核心组件之一,主要负责整个集群资源的调度功能,根据特定的调度算法和策略,将 Pod 调度到最优的工作节点上面去,从而更加合理.更加充分 ...

  7. 【Cocos2d-x 3.x】 调度器Scheduler类源码分析

    非个人的全部理解,部分摘自cocos官网教程,感谢cocos官网. 在<CCScheduler.h>头文件中,定义了关于调度器的五个类:Timer,TimerTargetSelector, ...

  8. Linux IO Scheduler(Linux IO 调度器)

    每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交的request.I/O调度器的基本目的是将请求按照它们对应在块设 ...

  9. cocos2d调度器(定时执行某函数)

    调度器(scheduler) 继承关系 原理介绍 Cocos2d-x调度器为游戏提供定时事件和定时调用服务.所有Node对象都知道如何调度和取消调度事件,使用调度器有几个好处: 每当Node不再可见或 ...

随机推荐

  1. centos7使用Dockerfile运行mysql库并初始化数据

    Dockerfile文件(文件名一定要这个) FROM mysql:5.7 WORKDIR /docker-entrypoint-initdb.d ENV LANG=C.UTF-8 ADD test. ...

  2. 【LeetCode】1418. 点菜展示表 Display Table of Food Orders in a Restaurant

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典统计边的次数 日期 题目地址:https://le ...

  3. 【LeetCode】169. Majority Element 解题报告(Java & Python & C+)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 思路 hashmap统计次数 摩尔投票法 Moore ...

  4. 【LeetCode】963. Minimum Area Rectangle II 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 线段长+线段中心+字典 日期 题目地址:https: ...

  5. 关于python常用的命令

    os模块: os.system os.system("cat/cmd等...") os.popen print os.popen("adb shell ls ../aa. ...

  6. CapstoneCS5265|TYPEC转HDMI 4K60HZ转换方案设计|CS5265功能介绍

    芯片简介描述:CS5265集成了一个DP1.4的转换器HDMI2.0转换.此外,CC控制器还用于CC通信,以实现DP Alt模式. CS5265是一种高度集成的单芯片,适用于多个细分市场和显示应用,如 ...

  7. Java高级大一结业认证考试试题 - 云南农业职业技术学院 - 互联网技术学院 - 美和易思校企合作专业

     第1题 .关于XML的文档结构描述错误的是 一个基本的XML文档通常由序言和文档元素两部分组成 XML文档中的序言可以包括XML声明.处理指令和注释 XML文档中的元素以树形结构排列 XML文档的声 ...

  8. Centos8 设置中文

    1.一般情况 1.1 进入设置选择 Region&Language 1.2 点击 加号 1.3 点击 汉语(中国) 1.4 选择 汉语(智能拼音) 2.特殊情况 有些虚拟机可能没有 汉语(智能 ...

  9. SpringBoot集成Actuator监控管理

    1.说明 本文详细介绍Spring Boot集成Actuator监控管理的方法, 基于已经创建好的Spring Boot工程, 然后引入Actuator依赖, 介绍监控管理相关功能的使用. Sprin ...

  10. HAproxy开启日志记录

    1.说明 HAproxy在默认情况不会记录日志, 不仅要在haproxy.conf中配置日志输出, 还需要修改系统日志的配置文件. 2.修改haproxy.conf 在haproxy.conf文件中增 ...