G-P-M模型

  • G:Goroutine,每个Goroutine对应一个G结构体,G存储Goroutine的运行堆栈、状态以及任务函数,可重用。

  • G并非执行体,每个G需要绑定到P才能调度执行。

  • P: Processor,表示逻辑处理器,对G来说,P相当于CPU核,G只有绑定到P才能被调度。对M来说,P提供了相关的执行环境(Context),如内存分配状态(mcache),任务队列(G)等。

  • P的数量决定了系统内最大可并行的G的数量(前提:物理CPU核数 >= P的数量)

  • M: Machine,OS内核线程抽象,代表着真正执行计算的资源,在绑定有效的P后,进入schedule循环;而schedule循环的机制大致是从Global队列、P的Local队列以及wait队列中获取。

  • M的数量是不定的,由Go Runtime调整,为了防止创建过多OS线程导致系统调度不过来,目前默认最大限制为10000个。

  • M并不保留G状态,这是G可以跨M调度的基础。

  • Sched:Go调度器,它维护有存储M和G的队列以及调度器的一些状态信息等。

举个简单的例子:工地上有若干砖头,地鼠借助小车把砖头运送到火种上去烧制。

M就可以看作图中的地鼠,P就是小车,G就是小车里装的砖。

​Go调度器中由两种不同的运行队列:全局运行队列(GRQ)和本地运行队列(LRQ)

  • GRQ:GRQ 适用于尚未分配给P的 Goroutines。

  • LRQ:每个P都有一个LRQ,用于管理分配给在P的上下文中执行的Goroutines,这些Goroutine轮流被和P绑定的M进行上下文切换。

G的数量可以远远大于M的数量,换句话说,Go程序可以利用少量的内核级线程来支撑大量Goroutine的并发。

  • 每个P均有本地队列,通过增加本地队列减少锁操作;

  • 一个P最多包含257个G:一个容量为126容量的本地队列+优先级最高的runnext;

  • 如果一个P上的G超过257个,就会将超过部分放到全局队列上 ,全局队列是一个链表,无限长。

调度策略

调度过程

调度顺序

  1. 如果P的runnext存在就用这个G【不加锁】;

  2. 从P的local queue中拿一个G【不加锁】;

  3. 从全局队列中拿一个G【加锁】,并且从全局队列中拿128个G到这个P中,如果不足128个则全部给他;

  4. 从netpoll拿一个G,剩下的injectglist放到全局队列中【加锁】;

  5. 随机其它P的本地队列中偷一半给当前P,将最后一个返回;

  6. 将P置为空闲,并且将M从P上拿下来,但是不会Kill M。

调度机制

  1. hand-off机制:当M由于G进行系统调用导致阻塞时,M会释放绑定的P,把P转移给其它空闲的M执行;

  2. work-stealing机制:当本P无可运行的G时,会尝试从其它P中偷取G,而避免了线程销毁。

减少拥塞

  1. 由于原子、互斥量或通道操作导致Goroutine阻塞,调度器会将当前阻塞的G切换出去,重新调度LRQ上的其他G;

  2. 由于网络请求或IO操作导致Goroutine阻塞,Go提供了专门的网络轮询器(NetPoller)来处理网络请求和IO操作的问题,其后台通过kqueue(MacOS),epoll(Linux)或 iocp(Windows)来实现IO多路复用。一旦G需要请求网络或IO则切换到网络轮询器上,完成操作后再回到原来的P进行排队;

  3. 由于调用系统方法导致的阻塞,此时不能使用网络轮询器,而系统会将当前M1进行阻塞,然后调度器将M1与P分离,同时调度器引入新的M2来服务P,阻塞完成后G1回到原来的P,而M1则等待以备下次使用;

  4. 由于G执行了sleep操作导致M阻塞,Go程序后台有一个监控线程sysmon,它监控那些长时间运行的G任务然后设置可以强占的标识符,别的Goroutine就可以抢先进来执行。只要下次这个Goroutine进行函数调用,那么就会被强占,同时也会保护现场,然后重新放入P的本地队列里面等待下次执行。

基于上述的GPM模型,Go就能实现在用户态的并发,从而降低并发所带来的线程切换性能开销。这也是后来包括腾讯、字节、Bilibili等公司以及开源框架拥抱Go的主要原因。另外由于Kubernetes和docker均是基于Go语言开发完成,使得CNCF相关的开源项目均为Go语言,最终导致云原生领域Go一家独大。但是Go也存在一些问题,这个我们后面再聊。

Go解密之路——GPM相关推荐

  1. ASP.NET AJAX 首部曲 - 迈向解密之路

    作者:章立民研究室 目的:简述ASP.NET AJAX以及其在实作上的便利性 版本:ASP.NET AJAX 1.0 Beta 2 出处:本文节录自章立民研究室正在撰写的「ASP.NET AJAX大解 ...

  2. BAT解密:互联网技术发展之路(5)- 开发层技术剖析

    BAT解密:互联网技术发展之路(5)- 开发层技术剖析 1. 开发框架 在系列文章的第2篇"BAT解密:互联网技术发展之路(2)- 业务如何驱动技术发展"中我们深入分析了互联网业务 ...

  3. BAT解密:互联网技术发展之路(1) - 技术发展的驱动力

    BAT解密:互联网技术发展之路(1) - 技术发展的驱动力 互联网行业是一个快速发展.快速变化的行业,新的业务.新的机会层出不穷,新的技术如雨后春笋般冒出,NoSQL.大数据.云.Node.js.Do ...

  4. 南通大学计算机学院顾飘,解密通大软件专业“学霸”们的考研之路_南通大学...

    解密通大软件专业"学霸"们的考研之路_南通大学南通大学 免费考研网/2018-05-13 谷雨时节,麦穗日渐饱满沉淀,考研的同学们也迎来了各自的收获季节.计算机科学与技术学院软件工 ...

  5. 云路php解密源代码_解密后乱码如何处理

    分为以下几种情况: 1.部分编辑器对中文的支持不好. 请重新解密后先使用windows系统下记事本程序打开文件,确认是否乱码,编辑器问题请自行修改编辑器设置解决. 2.部分文件可能加密了两次,解密后仍 ...

  6. 程序猿成长之路番外篇之前后端加解密(rsa+aes混合加解密算法)

    今年国庆前夕接手一个外部项目,说是要保障接口数据安全,数据安全相对容易些,接口安全嘛emmmmm, 这个要考虑加解密算法.白名单之类的问题了.于是打算今天搞一期接口安全为题的成长之路番外篇. 为什么要 ...

  7. alin的学习之路:加密相关知识(加密和解密,常见加密算法,消息验证码HMAC,数字签名)

    alin的学习之路:加密相关知识(加密和解密,常见加密算法,消息验证码HMAC,数字签名) 1. 加密和解密 1.1 加密的三要素 原始数据 加密操作: 明文 -> 密文 解密操作: 密文 -& ...

  8. BAT解密:互联网技术发展之路(4)- 存储层技术剖析

    BAT解密:互联网技术发展之路(4)- 存储层技术剖析 1. SQL 即关系数据.前几年NoSQL火了一阵子,很多人都理解为NoSQL是完全抛弃关系数据,全部采用非关系型数据,但事实经过几年的试验后, ...

  9. Retrofit2封装之路(请求参数加密解密)(二)

    Retrofit2 用例 public interface GitHubService {@GET("users/{user}/repos")Call<List<Rep ...

最新文章

  1. 点分治问题 ----------- 2019-2020 ICPC Asia Hong Kong Regional Contest C.Constructing Ranches[点分治+树状数组]
  2. python代码块所属关系的语法-天元高校邦数据科学通识课【Python基础语法】答案...
  3. 基于select模型的TCP服务器
  4. 【manacher】Strings in the Pocket
  5. 《全数据时代的炼金师》全书语言生动、易懂
  6. AndroidStudio安卓原生开发_UI高级_DrawerLayout_侧滑菜单控件---Android原生开发工作笔记120
  7. Memcached与Redis的区别和选择
  8. EditPlus 3设置字体大小
  9. 龙芯3A4000处理器简介
  10. Scratch基础(四):演奏音乐-两只老虎
  11. (十五)使用任务通知实现命令行解释器
  12. 4.8 单元格背景样式的设置 [原创Excel教程]
  13. collectionView的每一组的组头部和尾部的设置
  14. STM32+ESP8266连接电脑Qt网络上位机——QT篇
  15. 神经网络训练的一般步骤,神经网络训练过程详解
  16. 第3周课件-全网最详细的ORB-SLAM2精讲
  17. 关于召开山东省高职无人机应用技术专业教学指导方案开发第一次会议的通知...
  18. MDZZ我只想吐槽而已
  19. 前端ffmpeg实现视频剪切
  20. scenario知识点总结

热门文章

  1. 【亡羊补牢】挑战数据结构与算法 第18期 LeetCode 面试题 08.08. 有重复字符串的排列组合(递归与回溯)
  2. 激光打印机常见加粉问题与使用技巧
  3. java字符下落,重力球,加速下落减速上弹,重力下落,这段代码是看到网上一个关...
  4. 免费空间/硬盘/相册的集合。。。
  5. Python flask渲染模板注入
  6. WordNet发展概况
  7. WordNet 介绍(ICL-PKU)
  8. linux训练python出现killed_linux命令总结(二)
  9. spark提交python程序_Spark任务提交(Spark Submit)
  10. 如何批量制作倒序的流水号条形码