面试官:Go GMP 模型为什么 P 组件如此重要 ?

news2025/3/3 20:42:08

大家好,我是木川

Go GMP模型 是 Go语言并发性能的关键组成部分,它允许轻松创建大量的 Goroutines,设计思想包括并行性、线程复用以及抢占调度。

Go 1.1 版本前采用的是 GM 模型,存在一些问题,后面增加了 P 组件,实现了 GMP 模型。

一、什么是 GM 模型

Go 在 1.1 版本之前是 GM 模型,GM 模型包含 2 个重要结构,分别是 G、M,没有 P 组件。

f10db98836ba2e7119b8ebabca625a67.png

G(Goroutines):用户线程,通过 go 关键字创建,初始栈大小为 2-4K。

M(Machine):操作系统线程,进入一个调度循环,从全局队列中获取 G,切换到 G 的执行栈上并执行 G 的函数。

二、GM 模型存在的问题

全局队列的锁竞争

当 M 执行 G,必须访问全局队列,因为 M 有多个,当多线程访问同一资源需要加锁保证线程安全,导致激烈的锁竞争。

M 转移 G 增加额外开销

当 M1 在执行 G1 的时候, G1 包含创建新协程 G2,M1 创建了 G2,为了继续执行 G1,需要把 G2 保存到全局队列中,无法保证 G2 是被 M1 处理,造成了很差的局部性。

因为 M1 原本就保存了 G2 的信息,所以 G2 最好是在 M1 上执行,这样的话也不需要转移 G 到全局队列和线程上下文切换。

三、什么是 GMP 模型

为了解决 GM 模型上面存在的问题,在 GM 模型的基础上,新增了一个 P(Processor)组件,让 P 去管理这个 G 对象,M 想要运行 G,必须绑定 P,才能运行 P 所管理的 G。

GMP 模型包含 3 个重要结构,分别是 G、M、P。

e0b013174e19085712816aee3e8c24d8.png

G(Goroutines):用户线程,通过 go 关键字创建,初始栈大小为 2-4K。

M(Machine):操作系统线程,M 在绑定有效的 P 后,进入一个调度循环,从 P 中获取 G,切换到 G 的执行栈上并执行 G 的函数。

P(Processor):调度上下文,维护了一组 Goroutine 队列。

四、加了 P 之后解决的问题

  1. 每个 P 有自己的本地队列,大幅度减轻了对全局队列的直接依赖,减少了锁竞争。而 GM 模型的性能开销大头就是锁竞争。

  2. 局部性较好,当 M1 在执行 G1 的时候, G1 包含创建新协程 G2,M1 创建了 G2,直接将 G2 保存到当前绑定的 P 上,G2 大概率也是被 M1 执行,不需要将 G2 转移到全局 G 队列增加额外开销。

五、为什么 P 的逻辑不加到 M 上

  1. M 的数量都会多于 P(M 的数量默认上限是 10000,P 的默认数量是 CPU 核数), M 如果执行 G 发生系统阻塞调用,阻塞了 M,又不够用的情况下,M 会不断增加,如果本地 G 队列挂载在 M 上,那就意味着本地队列也会随之增加。如果 P 的逻辑加到 M上,导致本地队列的管理会变得复杂,且 work stealing 性能会大幅度下降。

  2. 如果 P 的逻辑直接加到 M 上,一旦 M 发生系统调用阻塞,会导致 P 上剩余的 G 也无法执行,G 的并发执行效率下降

六、总结

P 是 Go GMP 模型的关键组件,P 的存在防止一个阻塞的 Goroutine 阻塞整个 M,提高了应用程序的响应性,它在实现高效的并发性能、资源管理等方面发挥了至关重要的作用。

最后给自己的原创 Go 面试小册打个广告,如果你从事 Go 相关开发,欢迎扫码购买,目前 10 元买断,加下面的微信发送支付截图额外赠送一份自己录制的 Go 面试题讲解视频

cef207924728dd2d1b51e773bccf5710.jpeg

147042a79a90af7a39d961e42b10b64a.png

如果对你有帮助,帮我点一下在看或转发,欢迎关注我的公众号

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

哪种烧录单片机的方法合适?

哪种烧录单片机的方法合适? 首先,让我们来探讨一下单片机烧录的方式。虽然单片机烧录程序的具体方法会因为单片机型号、然后很多小伙伴私我想要嵌入式资料,通宵总结整理后,我十年的经验和入门到高级的学习资料,只需一…

计算机算法分析与设计(9)---0-1背包和完全背包问题(含C++代码)

文章目录 一、0-1背包概述1.1 问题描述1.2 算法思想 二、0-1背包代码2.1 题目描述2.2 代码编写 三、完全背包概述四、完全背包代码4.1 题目描述4.1 代码编写4.2 代码优化 一、0-1背包概述 1.1 问题描述 1. 0-1背包问题:给定 n n n 种物品和一背包。物品 i i i 的…

Unity可视化Shader工具ASE介绍——7、ASE实现Matcap效果和自定义节点

大家好,我是阿赵。继续介绍Unity可视化Shader编辑工具ASE。上一篇用了很长的篇幅来做了一个遮挡X光的效果。这一篇来做一个MatCap效果。不过做MatCap并不是目的,是想说明一下,怎样在ASE里面自定义方法节点。 一、在ASE里面做MatCap材质 由于…

【每日一题Day348】LC137只出现一次的数字Ⅱ | 状态转移

只出现一次的数字Ⅱ【LC137】 给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 **三次 。**请你找出并返回那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法且不使用额外空间来解决此问题。 排序 将数组从小到大…

LED灯的基本控制

题目要求 首先让8路LED指示灯闪烁3遍然后熄灭&#xff0c;接着依次点亮LED指示灯&#xff0c;最后依次熄灭LED灯&#xff0c;程序循环实现上述功能。 分析设计 原理图&#xff1a; 首先应该选通Y4C&#xff0c;也就是ABC 100。 代码 #include <regx52.h> #define…

C语言 —— 指针

目录 1. 指针是什么&#xff1f; 2. 指针和指针类型的关系 2.1 指针的解引用 2.2 指针-整数 3. 野指针 3.1 野指针成因 1. 指针未初始化 2. 指针越界访问 3. 指针指向的空间释放 3.2 如何规避野指针 4. 指针运算 4.1 指针-整数 4.2 指针-指针 指针-指针的使用 4.3 指针的关系运…

3.7 static关键字

思维导图&#xff1a; 3.7.1 静态属性 ### 3.7 static关键字 --- Java提供了一个称为static的关键字&#xff0c;用于修饰类的成员&#xff0c;如成员变量、成员方法和代码块。使用static修饰的成员拥有特殊性。 --- #### 3.7.1 静态属性 当属性被static关键字修饰时&…

嵌入式实时操作系统的设计与开发(轮询系统学习)

轮询系统具有以下工作特点&#xff1a;系统完成一个轮询的时间取决于循环中需要执行的函数个数。此外&#xff0c;轮询的次序是静态固定的&#xff0c;在运行时不能进行动态调整。 典型系统 许多工业线程网络中&#xff0c;由于需要控制的设备较多、相互距离又较远&#xff0…

手把手教你用Python绘制神经网络图

接下来教大家如何使用 Python 中的 networkx 库&#xff0c;绘制美观且标准的神经网络。会根据指定的层和节点数量&#xff0c;绘制不同结构的神经网络。 networkx 库可以用来创建和操作图类型的数据结构&#xff0c;其中包括无向图、有向图、带权图等等。 神经网络可以看做是一…

字节码之 Lambda 表达式底层原理

文章目录 0.前言0. lambda程序示例1. 编译程序&#xff1a;2. 使用 javap 分析字节码3. 输出字节码4. 分析指令 1. Lambda 表达式的字节码实现1.1 什么是invokedynamic 指令invokedynamic 的工作原理为何 invokedynamic 如此特殊&#xff1f; 1.2 bootstrap method 详解1.1 Lam…

Qt之给控件添加右键菜单

一、设置控件 在对应控件的属性中&#xff0c;将contextMenuPolicy设置为CustomContextMenu。 二、添加槽函数 在对应控件上右键选择槽函数customContextMenuRequested(QPoint)。 三、在槽函数中添加右键菜单 在槽函数中输入如下代码&#xff0c;添加右键菜单。 //右键菜单 …

红帽Linux的安装和部署

目录 一、红帽Linux的安装阶段 1、下载redhat7.9的iso镜像 2、安装阶段 二、红帽Linux的配置阶段 1、第一次进入装机配置 2、进入机器后的一些配置 三、远程连接阶段 1、关闭防火墙 2、使用Xshell远程连接&#xff08;其他连接工具也行&#xff09; 1.开启SSH服务 2.连…

二十、【钢笔工具组】

文章目录 钢笔工具自由钢笔工具弯度钢笔工具 钢笔工具 钢笔工具在photoshop作图中是一款使用频率较高的路径工具,我们可以在窗口选项栏中将路径编辑栏打开&#xff0c;如果我们需要选中使用路径&#xff0c;需要用到后边的路径工具才能去拖动&#xff0c;而选择工具不能拖动&a…

9月大型语言模型研究论文总结

大型语言模型(llm)在今年发展迅速&#xff0c;随着新一代模型不断地被开发&#xff0c;研究人员和工程师了解最新进展变得非常重要。本文总结9-10月期间发布了一些重要的LLM论文。 这些论文涵盖了一系列语言模型的主题&#xff0c;从模型优化和缩放到推理、基准测试和增强性能…

Sigma中的数字增益放大/降低方法

1 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)&#xff1f;加他微信hezkz17, 本群提供音频技术答疑服务

如何快速分析一款产品?

一、何时需要对一个产品进行分析&#xff1f; 首先&#xff0c;当你刚刚融入一个新的产品团队&#xff0c;尤其是当你需要深入了解你将负责的产品时&#xff0c;分析产品就显得尤为重要。这有助于你对产品的全面理解&#xff0c;发现其中的优势和不足&#xff0c;为未来的工作提…

14.5 Socket 应用组播通信

组播通信是一种基于UDP协议的网络通信方式&#xff0c;它允许发送方将消息同时传递给多个接收方。在组播通信中&#xff0c;发送方和接收方都会加入一个共同的组播组&#xff0c;这个组播组对应一个特定的IP地址&#xff0c;所有加入该组播组的主机都能够接收到发送方发送的消息…

C++概述

一、C特色 1.C是面向对象的高级程序设计语言 2.支持数据封装&#xff0c;将数据和对该数据进行操作的函数封装在一个类中&#xff0c;对象就是某一个具体的类。即类是数据封装的工具&#xff0c;对象是数据封装的实现。 3.具有继承性 4.具有函数重载 二、拓展介绍 1.C标准&a…

基于音频SOC开发板的主动降噪ANC算法源码实现

基于音频SOC开发板的主动降噪ANC算法源码实现 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,+群附加赠送降噪开发资料,

IO流:java中解码和编码出现乱码说明及代码实现

IO流&#xff1a;java中解码和编码的代码实现 一、UTF-8和GBK编码方式二、idea和eclipse的默认编码方式三、解码和编码方法四、代码实现编码解码 五、额外知识扩展 一、UTF-8和GBK编码方式 如果采用的是UTF-8的编码方式&#xff0c;那么1个英文字母 占 1个字节&#xff0c;1个…