侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

go语言中的GMP模型和GM模型浅析介绍

Go  /  管理员 发布于 2年前   1337

G: Goroutine

代表Go 协程Goroutine,存储了 Goroutine 的执行栈信息、Goroutine 状态以及 Goroutine 的任务函数等。G的数量无限制,理论上只受内存的影响,创建一个 G 的初始栈大小为2-4K,配置一般的机器也能简简单单开启数十万个 Goroutine ,而且Go语言在 G 退出的时候还会把 G 清理之后放到 P 本地或者全局的闲置列表 gFree 中以便复用。


M: 线程

Go 对操作系统线程(OS thread)的封装,可以看作操作系统内核线程,想要在 CPU 上执行代码必须有线程,通过系统调用 clone 创建。M在绑定有效的 P 后,进入一个调度循环,而调度循环的机制大致是从 P 的本地运行队列以及全局队列中获取 G,切换到 G 的执行栈上并执行 G 的函数,调用 goexit 做清理工作并回到 M,如此反复。M 并不保留 G 状态,这是 G 可以跨 M 调度的基础。M的数量有限制,默认数量限制是 10000,可以通过 debug.SetMaxThreads() 方法进行设置,如果有M空闲,那么就会回收或者睡眠。


P: Processor 本地队列

虚拟处理器,M执行G所需要的资源和上下文,只有将 P 和 M 绑定,才能让 P 的 runq 中的 G 真正运行起来。P 的数量决定了系统内最大可并行的 G 的数量,P的数量受本机的CPU核数影响,可通过环境变量$GOMAXPROCS或在runtime.GOMAXPROCS()来设置,默认为CPU核心数。

Sched:调度器结构,它维护有存储M和G的全局队列,以及调度器的一些状态信息


一.GM模型:

2012年前的调度器模型,使用了4年果断被抛弃,缺点如下:

1.  创建、销毁、调度G都需要每个M获取锁,这就形成了激烈的锁竞争。

2.  M转移G会造成延迟和额外的系统负载。

     比如当G中包含创建新协程的时候,M创建了G’,为了继续执行G,需要把G’交给M’执行,也造       成了很差的局部性,因为G’和G是相关的,最好放在M上执行,而不是其他M'。

3.  系统调用(CPU在M之间的切换)导致频繁的线程阻塞和取消阻塞操作增加了系统开销。


二.GMP模型:

P的数量:

由启动时环境变量`$GOMAXPROCS`或者是由`runtime`的方法`GOMAXPROCS()`决定


M的数量:

go语言本身的限制:

go程序启动时,会设置M的最大数量,默认10000.但是内核很难支持这么多的线程数

runtime/debug中的SetMaxThreads函数,设置M的最大数量

一个M阻塞了,会创建新的M。


P何时创建:

在确定了P的最大数量n后,运行时系统会根据这个数量创建n个P。


M何时创建:

没有足够的M来关联P并运行其中的可运行的G。比如所有的M此时都阻塞住了,而P中还有很多就绪任务,就会去寻找空闲的M,而没有空闲的,就会去创建新的M。


全场景解析:

1.P拥有G1,M1获取P后开始运行G1,G1创建了G2,为了局部性G2优先加入到P1的本地队列。

2.G1运行完成后,M上运行的goroutine切换为G0,G0负责调度时协程的切换。
 从P的本地队列取G2,从G0切换到G2,并开始运行G2。实现了线程M1的复用。

3.假设每个P的本地队列只能存4个G。
 G2要创建了6个G,前4个G(G3, G4, G5, G6)已经加入p1的本地队列,p1本地队列满了。

4.G2在创建G7的时候,发现P1的本地队列已满,
 需要执行负载均衡(把P1中本地队列中前一半的G,还有新创建G转移到全局队列),
 这些G被转移到全局队列时,会被打乱顺序

5.G2创建G8时,P1的本地队列未满,所以G8会被加入到P1的本地队列。

6.在创建G时,运行的G会尝试唤醒其他空闲的P和M组合去执行。
 假定G2唤醒了M2,M2绑定了P2,并运行G0,但P2本地队列没有G,M2此时为自旋线程

7.M2尝试从全局队列取一批G放到P2的本地队列,至少从全局队列取1个g,
 但每次不要从全局队列移动太多的g到p本地队列,给其他p留点。

8.假设G2一直在M1上运行,经过2轮后,M2已经把G7、G4从全局队列获取到了P2的本地队列
 并完成运行,全局队列和P2的本地队列都空了,那m就要执行work stealing(偷取):
 从其他有G的P哪里偷取一半G过来,放到自己的P本地队列。P2从P1的本地队列尾部取一半的G

9.G1本地队列G5、G6已经被其他M偷走并运行完成,当前M1和M2分别在运行G2和G8,
 M3和M4没有goroutine可以运行,M3和M4处于自旋状态,它们不断寻找goroutine。
 系统中最多有GOMAXPROCS个自旋的线程,多余的没事做线程会让他们休眠。

10.假定当前除了M3和M4为自旋线程,还有M5和M6为空闲的线程,
  G8创建了G9,G8进行了阻塞的系统调用,M2和P2立即解绑,P2会执行以下判断:
  如果P2本地队列有G、全局队列有G或有空闲的M,P2都会立马唤醒1个M和它绑定,
  否则P2则会加入到空闲P列表,等待M来获取可用的p。

11.G8创建了G9,假如G8进行了非阻塞系统调用。M2和P2会解绑,但M2会记住P2,
  然后G8和M2进入系统调用状态。当G8和M2退出系统调用时,会尝试获取P2,
  如果无法获取,则获取空闲的P,如果依然没有,G8会被记为可运行状态,
  并加入到全局队列,M2因为没有P的绑定而变成休眠状态

  • 上一条:
    Laravel Log Fake 2.0包用于断言/伪造记录/假日志
    下一条:
    go语言中将字符串切片转换为结构并使用反射方式读取数据
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2017-09
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-12
    • 2021-01
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-08
    • 2024-11
    • 2025-02
    • 2025-04
    • 2025-05
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客