疯狂编程网

  • 首页
  • 后端
    • GOLANG
    • PHP
  • 前端
  • 客户端
  • 服务器
  • AIGC
  • 开发工具
  • 代码人生
  • 关于本站
    • 联系我们
    • 免责声明
  1. 首页
  2. 后端
  3. GOLANG
  4. 正文

Golang GMP原理(1)

2023年5月10日 520点热度 0人点赞 0条评论

Golang GMP原理(1)

概念梳理

线程

线程一般指内核级线程,核心如下:

  1. 操作系统的最小调度单元
  2. 创建 销毁 调度由内核完成,cpu要完成内核态与用户态的转换
  3. 可充分利用多核,实现并行

协程

协程线程对应
image

协程,又称为用户级线程,核心点如下:

  1. 与线程存在映射关系,为M:1
  2. 创建、销毁、调度在用户态完成,对内核透明,所以更轻
  3. 从属同一个内核级线程,无法并行;一个协程阻塞会导致从属同一线程的所有协程无法执行。

Goroutine

Goroutine是特殊的协程

image

  1. 与线程存在映射关系,为M:N
  2. 创建、销毁、调度在用户态完成,对内核透明,足够轻便
  3. 可利用多个线程实现并行
  4. 通过调度器实现和线程间的动态绑定和调度
  5. 栈空间可动态扩缩。

对比

模型 弱依赖内核 可并行 可应对阻塞 栈可动态扩缩
线程 × √ √ ×
协程 √ × × ×
goroutine √ √ √ √

GMP模型

g

  1. g是goroutine,是对协程的抽象
  2. g有自己的运行栈、状态、以及执行的任务函数(用户通过go func指定)
  3. g需要绑定到p才能执行,在g的视角中,p是它的cpu

p

  1. p是调度器,联系g与m
  2. p的数量决定了g最大并行数量,可由用户通过GOMAXPROCS进行设定(超过CPU核数无意义)

m

  1. m是machine 是go中线程的抽象
  2. m不直接执行g,而是先和p绑定,由其实现代理
  3. 借由p的存在,m无需和g绑死,也无需记录g的状态信息,因此g在全生命周期中可实现跨m执行

gmp

image

  1. m是线程的抽象 g是goroutine p'是调度器
  2. m调度g前 需要和p绑定
  3. 全局有多个m和p 同时并行的g最大数量等于p的数量
  4. g的存放队列有三类:P的本地队列;全局队列;和wait队列(图中未展示,为io阻塞就绪态goroutine队列)
  5. m调度g时,优先取p本地队列,其次取全局队列,最后取wait队列;这样的好处是,取本地队列时,可以接近于无锁化,减少全局锁竞争;
  6. 为防止不同p的闲忙差异过大,设立work-stealing机制,本地队列为空的p可以尝试从其他p本地队列偷取一半的g补充到自身队列.
标签: golang
最后更新:2023年5月10日

大明

靠写代码养家的开发者。

点赞
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2023 疯狂编程网. ALL RIGHTS RESERVED.

京ICP备2022013580号-1