深入 Go 底层原理(四):GMP 模型深度解析

1. 引言

在上一篇文章中,我们宏观地了解了 Go 的调度策略。现在,我们将深入到构成这个调度系统的三大核心组件:GMP。理解 GMP 模型是彻底搞懂 Go 并发调度原理的关键。

本文将详细解析 G、M、P 各自的职责以及它们之间是如何协同工作的。

2. GMP 核心组件
  • G (Goroutine):

    • 定义:G 就是我们常说的 Goroutine。它是一个待执行的任务单元,包含了执行所需的栈空间指令指针 (PC) 以及其他状态信息(如 goroutine status)。

    • 特点:G 是轻量级的,初始栈大小仅为 2KB,可以根据需要动态伸缩。Go 程序可以轻松创建成千上万个 G。

    • 状态:G 有多种状态,如 _Gidle (闲置), _Grunnable (可运行), _Grunning (运行中), _Gsyscall (系统调用中), _Gwaiting (等待中), _Gdead (已死亡) 等。调度器根据这些状态来移动 G。

  • M (Machine):

    • 定义:M 是内核线程的抽象,是真正执行代码的实体。runtime 会限制 M 的数量,默认不超过 10000。

    • 职责:M 从一个关联的 P 的本地队列中获取 G,然后执行 G 的代码。如果 G 发生系统调用或阻塞,M 可能会与 P 解绑。

    • M0MM0是主线程,是程序启动时创建的第一个内核线程。

  • P (Processor):

    • 定义:P 是处理器的抽象,它代表了 M 执行 Go 代码所需的上下文资源。P 的数量在程序启动时被设置为 GOMAXPROCS 的值,通常等于 CPU 的核心数。

    • 职责:P 是 G 和 M 之间的“中间人”。它维护一个本地可运行 G 队列 (LRQ),为 M 提供可执行的 G。P 的存在使得调度器可以控制并发的程度(即同时有多少个 G 在真正地运行)。

    • 关键作用:P 的引入实现了 M 和 G 的解耦。当一个 M 因为其上运行的 G 进行系统调用而阻塞时,P 会从这个 M 上解绑,并去寻找一个空闲的 M(或创建一个新的 M)来继续执行自己队列中的其他 G。这使得 Go 的并发能力不会因为部分 Goroutine 的阻塞而受限。

3. GMP 的协作流程

一个典型的调度场景如下:

  1. 启动:程序启动,创建 M0,并创建 GOMAXPROCS 个 P。

  2. G 的创建go func() 创建一个新的 G。这个新的 G 会被优先放入当前 M 绑定的 P 的本地队列 (LRQ) 的队头。

  3. M 的执行循环

    • M 启动后,会绑定一个 P(acquirep)。

    • M 进入一个无限的调度循环 (schedule)。

    • 在循环中,M 尝试从 P 的 LRQ、全局队列 (GRQ) 或通过工作窃取 (runqsteal) 来获取一个可运行的 G。

    • 找到 G 后,M 会执行 G 的代码 (execute)。

    • G 执行完毕后,M 会再次进入调度循环寻找下一个 G。

  4. 系统调用场景 (Syscall):

    • 假设 M0 上的 G0 准备进行一个会阻塞的系统调用。

    • M0 会与它的 P0 解绑

    • P0 会去寻找一个空闲的 M(比如 M1)或者创建一个新的 M1。

    • P0 会绑定到 M1 上,并继续执行 P0 本地队列中的其他 G。

    • 与此同时,原来的 M0 则陷入系统调用,等待其完成。

    • 当 G0 的系统调用结束后,它会尝试获取一个空闲的 P 来继续执行。如果获取不到,G0 会被放入全局队列。M0 则会进入休眠。

这个设计使得 P(并发的许可证)不会因为 M 的阻塞而被浪费,从而保证了 GOMAXPROCS 个 Goroutine 可以持续地、并行地运行。

4. sysmon 监控线程

除了 G, M, P,还有一个重要的后台角色:sysmon。它是一个由 runtime 启动的、不需要 P 的 M,在后台执行以下任务:

  • 抢占:如上篇所述,向运行时间过长的 G 发送抢占信号。

  • 网络轮询 (netpoller):检查网络 I/O 是否就绪,并唤醒因此阻塞的 G。

  • GC 辅助:在需要时触发 GC。

  • 释放闲置资源:定期将长时间空闲的 M 和 P 的资源回收。

5. 总结

GMP 模型是 Go 语言高性能并发调度的核心。

  • G 是任务单元。

  • M 是执行实体(内核线程)。

  • P 是调度上下文和资源的提供者,是实现 M:N 模型的关键。

它们通过工作窃取、系统调用处理、异步抢占等机制紧密协作,构成了一个强大、高效、自适应的调度系统。

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

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

相关文章

AI赋能测试:技术变革与应用展望

AI 在测试中的应用:技术赋能与未来展望 目录 AI 在测试中的应用:技术赋能与未来展望 1. 引言 1.1 测试在软件开发中的重要性 1.2 AI 技术如何改变传统测试模式 1.3 文章结构概述 2. AI 在测试中的核心应用场景 2.1 自动化测试优化 2.1.1 智能测…

Mujoco(MuJoCo,全称Multi - Joint dynamics with Contact)一种高性能的物理引擎

Mujoco(MuJoCo,全称Multi - Joint dynamics with Contact)是一种高性能的物理引擎,主要用于模拟多体动力学系统,广泛应用于机器人仿真、运动学研究、人工智能等领域。以下是关于Mujoco仿真的一些详细介绍: …

winform-窗体应用的功能介绍(部分)

1--Point实现在窗口(Form)中一个按钮(控件)的固定位置(所在位置)一个按钮(控件)的位置一般是固定的,另一个按钮在窗口中位置是随机产生的Location属性:Location new Point(X,Y);在C#的Winform应用程序里,Button控件的鼠标悬标悬浮事件是不存在内置延迟时间的。当鼠标指针进入按…

最新Windows11系统镜像,23H2 64位ISO镜像

Windows 11 主要分为 Consumer Editions(消费者版)和 Business Editions(商业版)两大类别 。消费者版主要面向家庭和个人用户,商业版则侧重于企业和商业用户。这两大类别中存在部分重叠的版本,比如专业版和…

linux基本系统服务——DNS服务

一、DNS域名解析原理DNS&#xff0c;Domain Name System&#xff0c;域名系统&#xff1a;在互联网中由大量域名解析服务器共同提供的一整套关于“域名 <--> IP地址”信息查询的数据系统!!!! C/S架构&#xff1a;DNS服务端监听UDP 53端口&#xff08;处理客户端查询&…

数据处理和统计分析——08 apply自定义函数

1 apply()函数 1.1 apply()函数简介 Pandas提供了很多数据处理的API&#xff0c;但当提供的API不能满足需求的时候&#xff0c;需要自己编写数据处理函数, 这个时候可以使用apply()函数&#xff1b;apply()函数可以接收一个自定义函数&#xff0c;可以将DataFrame的行或列数据传…

C++冰箱管理实战代码

基于C++的冰箱管理实例 以下是一些基于C++的冰箱管理实例示例,涵盖不同功能场景,每个示例聚焦特定实现点,代码可直接扩展或整合到项目中。 示例1:基础冰箱类定义 class Refrigerator { private:int capacity;std::vector<std::string> items; public:Refrigerator(…

【Python】【数据分析】Python 数据分析与可视化:全面指南

目录1. 环境准备2. 数据处理与清洗2.1 导入数据2.2 数据清洗示例&#xff1a;处理缺失值示例&#xff1a;处理异常值2.3 数据转换3. 数据分析3.1 描述性统计3.2 分组分析示例&#xff1a;按年龄分组计算工资的平均值3.3 时间序列分析4. 数据可视化4.1 基本绘图示例&#xff1a;…

【AI】AIService(基本使用与指令定制)

【AI】AIService(基本使用与指令定制) 文章目录【AI】AIService(基本使用与指令定制)1. 简介2. AIService2.1 引入依赖2.2 编写AIService接口2.3 测试代码3. 指令定制3.1 系统提示词3.2 用户提示词1. 简介 AIService可以被视为应用程序服务层的一个组件&#xff0c;提供对应的…

AAAI赶稿后的心得

总结 已经第三次和老师们一起赶稿了&#xff0c;但是还是纰漏重重&#xff0c;每次都被我的垃圾写作给吓到。每次都手忙脚乱找不到重点&#xff0c;唉&#xff0c;我大概这辈子都成为不了郭老师&#xff1a; 自己把故事先捋清楚&#xff1a; 所有的东西都要抽象出来&#xff0c…

书籍推荐算法研究

## 项目概述本项目是一个完整的书籍推荐系统第五版(Complete Book Recommendation System V5),采用混合推荐策略,能够处理6种不同的用户场景,提供智能化的书籍推荐服务。## 系统架构### 核心设计思路系统采用**混合推荐策略**,结合了以下几种推荐算法:1. **协同过滤推荐…

工具自动生成Makefile

cmake 基础 cmake主要是生成Makefile&#xff0c;以便工程管理&#xff0c;只需要编写CMakeLists.txt安装camkesudo apt install cmake 安装cmake camke --version 查看cmake版本 sudo apt upgrade cmake 升级cmake源码隔离 在工程文件下创建一个build文件&…

Java项目:基于SSM框架实现的校园活动资讯网管理系统【ssm+B/S架构+源码+数据库+毕业论文+远程部署】

摘 要 使用旧方法对校园活动资讯进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在校园活动资讯的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。 这次开发的校园活动资讯网…

关于echarts的性能优化考虑

作为资深前端工程师&#xff0c;在处理 ECharts 性能问题时&#xff0c;核心思路是减少渲染压力、优化数据处理、避免不必要的计算&#xff0c;尤其在大数据量&#xff08;万级以上&#xff09;、高频交互或多图表场景下&#xff0c;性能优化尤为关键。以下是实战中验证过的有效…

汽车EDI:Vitesco EDI 项目案例

Vitesco Technologies&#xff08;纬湃科技&#xff09;脱胎于大陆集团的动力总成部门&#xff0c;是一家于2021年上市的全球领先汽车技术供应商。公司专注于电动出行领域&#xff0c;提供电驱动系统、电池管理系统、功率电子及热管理等关键技术解决方案。同时&#xff0c;其业…

译|Netflix 技术博客:一个利用视觉-语言模型和主动学习高效构建视频分类器的框架

本篇介绍了Netflix的视频标注器&#xff08;VA&#xff09;&#xff0c;一个利用视觉-语言模型和主动学习的交互式框架。其技术亮点在于通过人机协作系统&#xff0c;结合零样本能力和主动学习&#xff0c;引导领域专家高效标注视频数据&#xff0c;显著提升了模型样本效率和平…

前端应用权限设计面面观

目录 1. 权限设计:前端为啥要操这份心? 2. 权限模型的“内功心法”:RBAC 和 ABAC RBAC:简单粗暴的角色分配 ABAC:灵活但烧脑的属性控制 3. 权限数据的“物流体系”:从后端到前端的旅程 权限数据从哪儿来? 权限数据咋存? 权限数据咋用? 4. 路由守卫:权限的“第…

Javaweb————Apache Tomcat服务器介绍及Windows,Linux,MAC三种系统搭建Apache Tomcat

&#x1f3cd;️&#x1f3cd;️&#x1f3cd;️第一部分&#xff1a;什么是服务器&#xff1f; 服务器是远程的一个电脑,里面安装服务器程序监听对应的端口对外提供服务&#xff0c;可以根据用户的请求去获取对应的数据并返回给调用方。 &#x1f3cd;️&#x1f3cd;️&#…

winsock socket通讯为什么UDP服务器无法获取客户端IP?

针对VB6 Winsock开发中UDP服务器无法获取客户端IP的问题&#xff0c;以下是系统性排查方案&#xff1a; 一、基础协议特性确认UDP无连接特性 Winsock的UDP协议本身是无连接的&#xff0c;需通过GetPeerName方法主动获取对端IP&#xff0c;而非自动存储。数据接收处理 必须在Dat…

大模型时代,Transformer 架构中的核心注意力机制算法详解与优化实践

大模型时代&#xff0c;Transformer 架构中的核心注意力机制算法详解与优化实践Transformer 注意力机制深度解析与工业级优化实践一、注意力机制核心原理1.1 基础注意力公式1.2 多头注意力&#xff08;Multi-Head&#xff09;1.3 注意力机制可视化二、工业级优化技术2.1 计算效…