当前位置: 首页 > news >正文

GMP模型入门

go的并发实现采用的是M:N的线程模型,落地就是gmp模型。

M:N模型如下图:

gmp模型如下图:

---

Go 的 GMP 模型是其 高效并发调度机制的核心。GMP 代表:

  • G:Goroutine(用户态线程)

  • M:Machine(绑定内核线程)

  • P:Processor(调度器/执行上下文)

Go 通过这三个组件,实现了 goroutine 的调度和执行,避免了频繁的线程创建与上下文切换,性能优秀。

那么gmp模型是怎么实现的呢?

多个 Goroutine (G) -> 由 P 管理调度 -> 由 M(线程)实际执行;

具体来,需要执行的G是放在P的队列里面等着被执行调用的,不过有时候会有一些岔子,为了保证M的使用率,会有一些具体的调度算法,让G被调来调取,大概情况是:

  1. Hand off:比较重的调度;M阻塞了(syscall),就把M手头的G收走,让其他M去执行;

  2. Work Stealing:M对于的P中的队列没有G了,从其他地方调一些来

  3. 普通调度:G1阻塞了,例如sleep,io了,直接把G1挂起,让其他G被M执行。

  4. 等等

head off可以用图片来理解:

Hand off图源

----


整体的调度思路可以用伪代码来理解:

 // G = Goroutine,代表一个用户级线程(任务)// M = Machine,代表一个工作线程(对应一个内核线程)// P = Processor,代表执行资源(运行队列+执行上下文),M 必须绑定 P 才能运行 G​type G struct {fn func()    // Goroutine 要执行的函数}​type M struct {p *P         // 当前绑定的 Pcurg *G      // 当前正在执行的 G// ... 还有调用栈等}​type P struct {runQueue []*G    // 本地 G 队列// 还包括调度器上下文、调度时间等}​// 系统初始化时,创建 GOMAXPROCS 个 P,通常等于 CPU 核数func initRuntime() {for i := 0; i < GOMAXPROCS; i++ {allP[i] = new(P)}// 启动第一个 MstartM()}​// 启动一个 M(内核线程),从全局找可用的 P,然后调度func startM() {m := new(M)m.p = acquireP()   // 找一个空闲 Pgo m.run()         // 启动内核线程,进入调度循环}​// M 的主循环,持续运行 Gfunc (m *M) run() {for {g := m.p.findRunnableG() // 找到一个可运行的 Gif g == nil {// 若本地队列空了,可以尝试 steal 其他 P 的 Gg = stealFromOtherP()if g == nil {// 若仍找不到,当前 M 休眠stopM(m)return}}m.curg = grunG(g) // 运行 G 的函数m.curg = nil}}​// P 的调度器,从本地 runQueue 中找 goroutinefunc (p *P) findRunnableG() *G {if len(p.runQueue) == 0 {return nil}g := p.runQueue[0]p.runQueue = p.runQueue[1:]return g}​// 当调用 go f() 时,生成一个新的 G,并放入当前 P 的队列func goNew(f func()) {g := &G{fn: f}curP := currentM().pcurP.runQueue = append(curP.runQueue, g)// 若当前 M 忙不过来,可触发 newM 让新线程帮忙跑 G}
 ​

参考资料:

深入浅出 Go 语言 GMP 模型 

刘丹冰 【Golang深入理解GPM模型】https://www.bilibili.com/video/BV19r4y1w7Nx/?share_source=copy_web&vd_source=4ab2dac702abaae48d1782021ca7150c

相关文章:

  • Rules and Monetization
  • 【JavaScript-Day 20】揭秘函数的“记忆”:深入浅出理解闭包(Closure)
  • 【MySQL】实战时遇到的几个 tips
  • ​宠智灵AI诊疗助手:打造宠物医疗的“第二医生”与智能化引擎
  • MySQL--day6--单行函数
  • 机器人强化学习入门学习笔记(四)
  • React从基础入门到高级实战:React 基础入门 - 状态与事件处理
  • 聚焦 Microsoft Fabric,释放数据潜力
  • CAS详解
  • 第三章 软件工程模型和方法
  • 初识Flask框架
  • 直线导轨运转过程中如何避免震动发生?
  • 量子传感器:开启微观世界的精准探测
  • VSCode如何像Pycharm一样“““回车快速生成函数注释文档?如何设置文档的样式?autoDocstring如何设置自定义模板?
  • 3dczml时间动态图型场景
  • Linux里more 和 less的区别
  • 【自定义类型-联合和枚举】--联合体类型,联合体大小的计算,枚举类型,枚举类型的使用
  • 中国经济的结构性困境与制度性瓶颈:关键卡点深度解析
  • 撤销Conda初始化
  • PyTorch 中unsqueeze(-1)用法
  • 学做标书网站/免费网站推广网站短视频
  • 鞋子网站模板/北京线上教学
  • 做装修公司网站费用/武汉关键词排名提升
  • 网站建设第一品牌 网站设计/东莞做网站推广的公司
  • 网站建设国内排行/什么平台发广告最有效
  • 新手如何做网站的教程/株洲seo优化首选