深入理解Golang调度器:MPG模型与并发调度单元

深入理解Golang调度器:MPG模型与并发调度单元

under-the-hood 📚 Go: Under The Hood | Go 语言原本 | https://golang.design/under-the-hood under-the-hood 项目地址: https://gitcode.com/gh_mirrors/un/under-the-hood

引言

Go语言的并发模型是其核心特性之一,而调度器则是实现这一特性的关键组件。本文将深入探讨Go调度器的MPG模型,帮助读者理解Go语言如何高效地管理并发任务。

MPG模型概述

Go调度器采用了一种称为MPG的模型,由三个核心组件构成:

1. G (Goroutine)

Goroutine是Go语言中的轻量级线程,由Go运行时管理而非操作系统。每个Goroutine都有自己的执行栈,但相比操作系统线程更加轻量。

2. M (Machine)

M代表操作系统线程,是实际执行代码的实体。每个M都与一个操作系统线程一一对应。

3. P (Processor)

P是一个逻辑处理器,负责管理Goroutine的执行。P的数量通常等于CPU核心数,可以通过GOMAXPROCS调整。

调度器工作原理

工作线程的状态管理

Go调度器需要平衡两个关键性质:

  1. 当Goroutine数量超过M数量时,部分Goroutine需要等待执行
  2. 当Goroutine数量少于M数量时,部分M需要暂停以节省资源

调度器通过引入"自旋线程"的概念来解决这个问题:

  • 自旋线程:没有任务可执行但保持活跃状态的M
  • 非自旋线程:被暂停的M

状态转换机制

调度器维护以下状态转换:

执行 → 自旋 → 暂止
↑        |
+--------+

当一个新的Goroutine就绪时,调度器会优先检查是否有自旋线程可用,而不是立即创建新线程。

核心数据结构

M结构

type m struct {
    g0      *g       // 调度器使用的特殊Goroutine
    curg    *g       // 当前正在执行的Goroutine
    p       puintptr // 关联的P
    spinning bool    // 是否处于自旋状态
    // ... 其他字段
}

P结构

type p struct {
    status uint32   // 状态(idle/prunning/...)
    runq   [256]guintptr // 本地Goroutine队列
    runnext guintptr     // 下一个要运行的Goroutine
    // ... 其他字段
}

G结构

type g struct {
    stack       stack   // 执行栈
    sched       gobuf   // 调度上下文
    atomicstatus uint32 // Goroutine状态
    // ... 其他字段
}

初始化过程

Go程序的启动过程涉及MPG三者的初始化:

  1. M初始化:创建主线程并初始化相关字段
  2. P初始化:根据GOMAXPROCS设置创建P
  3. G初始化:创建主Goroutine并准备执行

P的初始化细节

P的初始化通过procresize函数完成,主要步骤包括:

  1. 调整全局P列表(allp)的大小
  2. 初始化新的P对象
  3. 将多余的P资源释放
  4. 将空闲P放入空闲链表

G的创建过程

Goroutine的创建通过newproc函数完成,关键步骤包括:

  1. 获取函数参数和调用信息
  2. 从P的空闲G列表获取或新建G
  3. 设置G的执行栈和调度上下文
  4. 将G放入P的运行队列

调度器调优

GOMAXPROCS的作用

runtime.GOMAXPROCS允许动态调整P的数量,但需要注意:

  1. 调整P数量会触发STW(Stop The World)
  2. 设置值小于1时不会生效
  3. 频繁调整可能影响性能

总结

Go调度器的MPG模型通过精细的状态管理和工作窃取算法,实现了高效的并发任务调度。理解这些底层机制有助于开发者编写更高效的并发代码,并在性能调优时做出更明智的决策。

调度器的设计体现了Go语言在并发编程方面的核心理念:通过轻量级的Goroutine和高效的调度机制,让开发者能够以简单的方式编写高性能的并发程序,而无需过度关注底层细节。

under-the-hood 📚 Go: Under The Hood | Go 语言原本 | https://golang.design/under-the-hood under-the-hood 项目地址: https://gitcode.com/gh_mirrors/un/under-the-hood

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

资源下载链接为: https://pan.quark.cn/s/3d8e22c21839 随着 Web UI 框架(如 EasyUI、JqueryUI、Ext、DWZ 等)的不断发展成熟,系统界面的统一化设计逐渐成为可能,同时代码生成器也能够生成符合统一规范的界面。在这种背景下,“代码生成 + 手工合并”的半智能开发模式正逐渐成为新的开发趋势。通过代码生成器,单表数据模型以及一对多数据模型的增删改查功能可以被直接生成并投入使用,这能够有效节省大约 80% 的开发工作量,从而显著提升开发效率。 JEECG(J2EE Code Generation)是一款基于代码生成器的智能开发平台。它引领了一种全新的开发模式,即从在线编码(Online Coding)到代码生成器生成代码,再到手工合并(Merge)的智能开发流程。该平台能够帮助开发者解决 Java 项目中大约 90% 的重复性工作,让开发者可以将更多的精力集中在业务逻辑的实现上。它不仅能够快速提高开发效率,帮助公司节省大量的人力成本,同时也保持了开发的灵活性。 JEECG 的核心宗旨是:对于简单的功能,可以通过在线编码配置来实现;对于复杂的功能,则利用代码生成器生成代码后,再进行手工合并;对于复杂的流程业务,采用表单自定义的方式进行处理,而业务流程则通过工作流来实现,并且可以扩展出任务接口,供开发者编写具体的业务逻辑。通过这种方式,JEECG 实现了流程任务节点和任务接口的灵活配置,既保证了开发的高效性,又兼顾了项目的灵活性和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌朦慧Richard

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值