【修正版】动图图解!GMP模型里为什么要有P?背后的原因让人暖心

简介: 【修正版】动图图解!GMP模型里为什么要有P?背后的原因让人暖心

GM模型是什么

GM图

Go 1.1版本之前,其实用的就是GM模型。

  • G,协程。通常在代码里用  go  关键字执行一个方法,那么就等于起了一个G
  • M内核线程,操作系统内核其实看不见GP,只知道自己在执行一个线程。GP都是在用户层上的实现。

除了GM以外,还有一个全局协程队列,这个全局队列里放的是多个处于可运行状态GM如果想要获取G,就需要访问一个全局队列。同时,内核线程M是可以同时存在多个的,因此访问时还需要考虑并发安全问题。因此这个全局队列有一把全局的大锁,每次访问都需要去获取这把大锁。

并发量小的时候还好,当并发量大了,这把大锁,就成为了性能瓶颈


GM模型

GMP模型是什么

GMP图

基于没有什么是加一个中间层不能解决的思路,golang在原有的GM模型的基础上加入了一个调度器P,可以简单理解为是在GM中间加了个中间层。

于是就有了现在的GMP模型里。

  • P 的加入,还带来了一个本地协程队列,跟前面提到的全局队列类似,也是用于存放G,想要获取等待运行的G,会优先从本地队列里拿,访问本地队列无需加锁。而全局协程队列依然是存在的,但是功能被弱化,不到万不得已是不会去全局队列里拿G的。
  • GM模型里M想要运行G,直接去全局队列里拿就行了;GMP模型里,M想要运行G,就得先获取P,然后从 P 的本地队列获取 G

GMP模型

  • 新建 G 时,新G会优先加入到 P 的本地队列;如果本地队列满了,则会把本地队列中一半的 G 移动到全局队列。
  • P 的本地队列为空时,就从全局队列里去取。


GMP模型-获取全局协程队列

  • 如果全局队列为空时,M 会从其他 P 的本地队列偷(stealing)一半G放到自己 P 的本地队列。


GMP模型-stealing

  • M 运行 GG 执行之后,M 会从 P 获取下一个 G,不断重复下去。

GMP模型-循环执行

为什么P的逻辑不直接加在M上

主要还是因为M其实是内核线程,内核只知道自己在跑线程,而golang的运行时(包括调度,垃圾回收等)其实都是用户空间里的逻辑。操作系统内核哪里还知道,也不需要知道用户空间的golang应用原来还有那么多花花肠子。这一切逻辑交给应用层自己去做就好,毕竟改内核线程的逻辑也不合适啊。

如果文章对你有帮助,看下文章底部右下角,做点正能量的事情(点两下)支持一下。(疯狂暗示,拜托拜托,这对我真的很重要!

目录
相关文章
|
存储 缓存 安全
90%的Go语言程序员map遍历方式都是错的
90%的Go语言程序员map遍历方式都是错的
987 0
|
缓存 Kubernetes API
K8S 性能优化 - K8S APIServer 调优
K8S 性能优化 - K8S APIServer 调优
|
前端开发 JavaScript Go
【golang之路】——govaluate
【golang之路】——govaluate
58442 5
【golang之路】——govaluate
|
JavaScript Java 关系型数据库
Springboot+vue的课程管理系统(教务管理系统)。Javaee项目,springboot vue前后端分离项目。
Springboot+vue的课程管理系统(教务管理系统)。Javaee项目,springboot vue前后端分离项目。
|
11月前
|
消息中间件 编解码 Kafka
Go语言并发模型与模式:Worker Pool 模式
Worker Pool(工作池)模式是Go语言中管理高并发任务的有效方法。通过限制 Goroutine 数量,避免资源耗尽或系统崩溃。其核心包括任务通道、工作者 Goroutine、结果通道(可选)及同步机制。示例代码展示了如何分配与处理任务,同时支持带返回值的实现。该模式适用于网络服务、批量任务处理、消息消费等场景,具有限制并发、提高稳定性和结构清晰的优点。但需注意通道关闭时机、任务取消机制及错误处理等问题。Worker Pool 是构建高效任务处理系统的强大工具。
|
存储 数据采集 缓存
Bitmap 和 布隆过滤器傻傻分不清?你这不应该啊
大家好,我是小富。本文介绍了 Redis 的 Bitmap 和布隆过滤器的区别与关系,包括它们的底层原理、应用场景及优缺点。Bitmap 以 bit 为单位存储数据,适用于记录二值状态,如用户签到、在线状态等。布隆过滤器通过多个哈希函数优化哈希碰撞问题,适用于大规模数据的快速判断,如缓存穿透、邮箱黑名单过滤等。两者都能高效处理大数据量和高并发场景。
939 122
|
自然语言处理 API 开发者
DeepSeek-Free-API:DeepSeekV3免费的api接口,需要使用api方式的同学可以参考一下这个项目,可以收藏起来试一下
嗨,大家好,我是小华同学。今天为大家介绍一个开源项目——DeepSeek V3 Free 服务。该项目基于 DeepSeek-V3 R1 大模型,提供免费、高性能的 API,支持高速流式输出、多轮对话、联网搜索和深度思考等功能。适用于智能客服、内容创作、教育辅助等场景。部署方式灵活,支持 Docker、Docker-compose、Render、Vercel 和原生部署。欢迎关注我们,获取更多优质开源项目和高效工作学习方法。
3213 15
|
存储 监控 Java
Go Goroutine 究竟可以开多少?(详细介绍)
Go Goroutine 究竟可以开多少?(详细介绍)
393 3
|
编译器 Go
Go语言常量完全手册 const用法看这一篇就够了
Go语言常量完全手册 const用法看这一篇就够了
1338 0
|
Prometheus Kubernetes 监控
NVIDIA GPU Operator分析六:NVIDIA GPU Operator原理分析
背景我们知道,如果在Kubernetes中支持GPU设备调度,需要做如下的工作:节点上安装nvidia驱动节点上安装nvidia-docker集群部署gpu device plugin,用于为调度到该节点的pod分配GPU设备。除此之外,如果你需要监控集群GPU资源使用情况,你可能还需要安装DCCM exporter结合Prometheus输出GPU资源监控信息。要安装和管理这么多的组件,对于运维
3707 0

热门文章

最新文章