go学习-GMP模型

GMP 好理解还是 GPM 好理解?

在这里插入图片描述
按照上述图,从上往下,GPM更适合理解
GMP 模型: Go 语言运行时系统中的 Goroutine、用于管理 Goroutine 调度的 Go Scheduler(P)、机器可用的逻辑处理器数量(M)。

理解GPM

G

每个 Goroutine 是一个轻量级“线程”,称之为“协程”,可由 Go 运行时系统并发执行

G与P的关系

Goroutine 通过 Go Scheduler 调度运行
Go Scheduler 负责在适当时间调度 Goroutine 的执行
并在必要时将 Goroutine 阻塞和调度到其他 Goroutine 执行上下文

P

P 是中介者,连接 Goroutine 和 M,由于 Go Scheduler 在用户 CPU 时间片内并行执行 Goroutine,因此也必须用 P 进行有效的调度。
Go 运行时系统可以自动调整 P 的数量,以确保它们与当前运行的 Goroutine 的数量大致相同,并且可以在需要更多/更少 P 时及时适应。

P 叫 go运行时的逻辑并发单元,每个OS线程需要获取一个P才能执行
每个P中都包含运行一个线程所需的全部资源(比如线程栈),包括存放G的就绪队列,以及分配堆内存所需的地址空间等
这些在运行main.main前就在runtime.main中(程序启动时)创建好,所以并发执行时就可以避免冲突

P的本地队列上限默认最多 GOMAXPROCS = 256 个,如果想要更改队列长度限制,使用 runtime.GOMAXPROCS(n) 调整

M

M 是处理器,绑定一个具体的OS线程(内核线程),Goroutine 运行的上下文在这里被调度并执行,所以也是 Goroutine 执行的上下文
管理 Goroutine 的运行状态、切换执行上下文
Go 运行时系统会根据机器硬件和条件动态地分配这些处理器,以确保 Goroutine 能够高效地并发运行

一个 M 最多有一个空闲的 P,有一个M阻塞,会创建或者唤醒一个新的M;若有空闲,则会回收或睡眠此M。
全局队列作为一个候选队列,可以同时为不同的 P 提供 Goroutine,从而使 Goroutine 尽快找到执行线程(M)
如果所有的 P 的本地队列都已满,并且全局队列也已满,Go 运行时系统将通过动态增加 M 的数量来解决压力
以尽快地使 Goroutine 开始运行,但OS是否愿意加M,则需要根据系统负载来定。

在默认情况下,全局队列的大小是默认 P 的数量的系数,最小值为 4,最大值为 32768

OS分配到当前Go程序的内核线程数

使用 runtime.NumCPU() 查询M数量,返回当前系统可用的逻辑处理器数量

返回值可能会因为不同的操作系统和系统配置而有所不同
有些操作系统可能会在系统负载高峰期动态增加或减少 M 的数量,以适应不同的负载需求
只会返回运行时系统认为当前可用的逻辑处理器数量,而不是一成不变的固定值

当所有 P 的本地队列都已满,且全局队列也满时,有新的Goroutine就绪

  • Go 运行时系统会请求操作系统分配更多线程,以进一步提高系统并发处理的能力,启动一个新线程,即新的 M (machine)
  • 新的 M 将从全局队列中拿走一个等待 Goroutine 并开始运行它
  • 新的 M 将在全局队列和所有本地队列之间轮询,直到所有队列都变得空闲或有 Goroutine 准备好运行,这将减少因 Goroutine 等待执行带来的延迟

GMP 特点

Go 语言的并发性能和可伸缩性得到了最大化的利用。
当 CPU 资源充足时,它可以在 Goroutine 和 P 之间平衡负载,并在适当的时候调度 Goroutine 到合适的 M 上以保证运行效率

Go 协程调度为什么优于线程

多进程/多线程问题

进程/线程数量越多,切换成本越大
多进程/多线程的壁垒:高内存占用,高CPU调度切换
同步竞争,如锁等

协程如何设计

N:1 : 无法利用多个CPU,出现阻塞瓶颈
​1:1 :和多线程、多进程无区别,切换协程成本代价昂贵
​M:N :能够利用多核,过度依赖协程调度器的优化和算法

如何高效

复用线程

避免频繁的创建、销毁线程,而是对线程的复用

Work stealing机制 (work偷窃)

当本线程的P队列中没有G可用并且全局队列为空时,会主动去其他线程的P队列中获取,避免线程的销毁

handle off 机制

当本线程的G运行阻塞时,会释放绑定的P队列,把P队列转移到其他空闲的线程上去

利用并行

GOMAXPROCS设置P的数量,最多有GOMAXPROCS个线程分布在CPU上运行

抢占

一个Goroutine 最多占用CPU 10ms 就会交给其他协程,防止其被饿死
Go 语言的抢占是基于协作式调度的,而切换的主动权在 Goroutine 执行上

  • 通过代码的设计来主动让 Goroutine 放弃控制权,以便让其它 Goroutine 获得执行时间片
    使用 runtime.Gosched() 主动让当前 Goroutine 放弃 CPU 控制权,使当前 Goroutine 立即进入就绪状态,并重新排队等待下一次调度
  • 内部编写超时限制的代码来防止 Goroutine 长时间执行

Go如何调整协程优先级?
在 Go 语言中,所有 Goroutine 都有相同的默认优先级,不能直接通过代码来调整 Goroutine 的优先级
这个是不是一个协程的缺点?我觉着是

全局G队列

当M执行work stealing 机制时,无法从其他P中获取G,就会从全局队列中获取

总结

G是买家,M是卖家,M根据最近的行情,动态调整,也可以去抢其他M的活
G呢,买的东西也不知道是哪个M操办的,G之间是公平的

参考文档

https://juejin.cn/post/7119307307728994335

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/138885.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

竞赛选题 基于深度学习的目标检测算法

文章目录 1 简介2 目标检测概念3 目标分类、定位、检测示例4 传统目标检测5 两类目标检测算法5.1 相关研究5.1.1 选择性搜索5.1.2 OverFeat 5.2 基于区域提名的方法5.2.1 R-CNN5.2.2 SPP-net5.2.3 Fast R-CNN 5.3 端到端的方法YOLOSSD 6 人体检测结果7 最后 1 简介 &#x1f5…

计算机网络常见面试题

目录 一、谈一谈对OSI七层模型和TCP/IP四层模型的理解? 答:OSI七层模型主要分为: TCP/IP四层协议: 二、谈谈TCP协议的3次握手过程? 三、TCP协议为什么要3次握手?2次,4次不行吗? …

关于IDEA没有显示日志输出?IDEA控制台没有显示Tomcat Localhost Log和Catalina Log 怎么办?

问题描述: 原因是;CATALINA_BASE里面没有相关的文件配置。而之前学习IDEA的时候,把这个文件的位置改变了。导致,最后输出IDEA的时候,不会把日志也打印出来。 检查IDEA配置; D:\work_soft\tomcat_user\Tomcat10.0\bin 在此目录下&…

华为OD机试 - 构成正方形的数量 - 数据结构map(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、Java算法源码五、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷)》。 …

浅谈建筑能耗智能监测平台发展现状及未来趋势

安科瑞 华楠 摘要:文章以每年发布的上海市国家机关办公建筑和大型公共建筑能耗监测及分析报告变化为切入点,分析了历年能耗分析报告的内容和功能变化;介绍了上海市国家机关办公建筑和大型公共建筑能耗监测平台发展和应用历程;揭示…

基于SpringBoot的网上超市系统的设计与实现

目录 前言 一、技术栈 二、系统功能介绍 管理员功能实现 用户功能实现 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 网络技术和计算机技术发展至今,已经拥有了深厚的理论基础,并在现实中进行了充分运用,尤其是基于计…

OpenHarmony Meetup常州站招募令

OpenHarmony Meetup 常州站正火热招募中! 诚邀充满激情的开发者参与线下盛会~ 探索OpenHarmony前沿科技,畅谈未来前景, 感受OpenHarmony生态构建之路的魅力! 线下参与,名额有限,仅限20位幸运者&#xff01…

npm常用命令系统介绍

npm常用命令系统介绍 npm helpnpm initpackage.json 文件package.json 文件属性说明默认 package.json 文件--参数[-yes|-y]设置 package.json 中字段的默认值package-lock.json 文件 npm [config|c]设置源 npm [install|i]可选参数:全局安装的特性 包的删除npm uni…

Python教程(14)——Python函数的入门学习

函数是什么?在编程中,函数是一段可重用的代码块,用于完成特定任务或执行特定操作。它可以接输入参数并返回一个值或执行一系列操作。函数可以帮助程序员将代码模块化,提高代码的可读性和可维护性。 函数通常包括以下组成部分&…

Gateway学习和源码解析

文章目录 什么是网关?搭建实验项目demo-servicegateway-service尝试简单上手 路由(Route)断言(Predicate)和断言工厂(Predicate Factory)gateway自带的断言工厂After(请求必须在某个…

STM32 Cubemx 通用定时器 General-Purpose Timers同步

文章目录 前言简介cubemx配置 前言 持续学习stm32中… 简介 通用定时器是一个16位的计数器,支持向上up、向下down与中心对称up-down三种模式。可以用于测量信号脉宽(输入捕捉),输出一定的波形(比较输出与PWM输出&am…

【AI视野·今日NLP 自然语言处理论文速览 第三十七期】Thu, 21 Sep 2023

AI视野今日CS.NLP 自然语言处理论文速览 Thu, 21 Sep 2023 Totally 57 papers 👉上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Chain-of-Verification Reduces Hallucination in Large Language Models Authors Shehzaad Dhuliawala, Mojt…

计算机网络相关知识点

谈一谈对OSI七层模型和TCP/IP四层模型的理解? 这两种模型都是网络通信中重要的参考模型,他们的设计和功能有一些区别。 首先OSI,OSI七层模型,也被称为开放系统互联参考模型,是一种在国际标准化组织(ISO)中…

HEC-RAS 1D/2D水动力与水环境模拟教程

详情点击公众号技术科研吧链接:HEC-RAS 1D/2D水动力与水环境模拟教程 前言 水动力与水环境模型的数值模拟是实现水资源规划、环境影响分析、防洪规划以及未来气候变化下预测和分析的主要手段。然而,一方面水动力和水环境模型的使用非常复杂&#xff0c…

Elasticsearch8.X与java调用

1、ES增删改查操作 https://blog.csdn.net/UbuntuTouch/article/details/123839857 https://huaweicloud.csdn.net/637ef6b7df016f70ae4cac57.html 2、java与ES8相关maven依赖 https://blog.csdn.net/boling_cavalry/article/details/125351161 3、kibana下载数据 3、kibana相…

【C语言】数组和指针刷题练习

指针和数组我们已经学习的差不多了,今天就为大家分享一些指针和数组的常见练习题,还包含许多经典面试题哦! 一、求数组长度和大小 普通一维数组 int main() {//一维数组int a[] { 1,2,3,4 };printf("%d\n", sizeof(a));//整个数组…

有趣的设计模式——适配器模式让两脚插头也能使用三孔插板

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 场景与问题 众所周知,我们国家的生活用电的电压是220V而笔记本电脑、手机等电子设备的工作压没有这么高。为了使笔记本、手机等设备可以使用220V的生活用电就需…

机器学习笔记:概念对比——损失函数,代价函数,目标函数

损失函数 Loss Function 通常是针对单个训练样本而言 给定一个模型输出 和一个真实值y ,损失函数是 代价函数 Cost Function 通常是针对整个训练集(或者在使用 mini-batch gradient descent 时一个 mini-batch)的总损失 目标函数 Objec…

HCIE-容器docker

1、安装配置操作系统,使用CentOS stream 8镜像 之前:RHEL 8.4 发布了,CentOS紧随其后,发布CentOS 8.4 之后:CentOS 走在前面,成为RHEL上游,再去发布RHEL 制作模板,模板配置要求&…

计算机视觉与深度学习-全连接神经网络-训练过程-批归一化- [北邮鲁鹏]

文章目录 思想批归一化操作批归一化与梯度消失经过BN处理 算法实现 思想 直接对神经元的输出进行批归一化 批归一化:对输出值进行归一化,将归一化结果平移缩放作为输出。 批归一化操作 小批量梯度下降算法回顾:每次迭代时会读入一批数据&am…