首页 游戏 软件 资讯 排行榜 专题
首页
编程语言
Golang 的 G-M-P 模型是怎么提升并发性能的

Golang 的 G-M-P 模型是怎么提升并发性能的

热心网友
20
转载
2026-05-03

Golang GMP模型:高并发背后的调度艺术

Golang 的 G-M-P 模型是怎么提升并发性能的

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

很多人误以为Go的高并发是靠堆砌线程实现的,其实不然。GMP模型的精髓,恰恰在于解耦了Goroutine(G)、OS线程(M)和逻辑处理器(P)三者之间的关系。它让调度器能够动态复用数量有限的OS线程,从而轻松支撑起海量轻量级Goroutine的调度。这才是性能提升的关键。

为什么goroutine创建快、数量多却不压垮系统

秘诀在于“轻量”二字。一个Goroutine的初始栈只有2KB,并且能按需动态扩缩。创建时,它仅仅分配一个结构体和栈头,并不会立即向操作系统申请线程资源。相比之下,一个典型的OS线程默认栈就有1到8MB。所以,一句简单的go func(){}()开销极低。实践中,轻松启动十万个Goroutine也不会触发内存溢出(OOM),但如果换成十万个pthread,系统恐怕早就因为内存和调度器过载而崩溃了。

关键在于,G的生命周期完全由运行时(runtime)管理,并不与特定的M绑定。这意味着:

  • 当一个G阻塞时(比如执行ch <- vtime.Sleepnet.Read),它所在的M可以立刻脱身,去执行其他就绪的G,而它原先绑定的P和本地任务队列都不会丢失。
  • 即使有大量G处于等待状态,M的数量也不会线性增长。运行时非常“吝啬”,只在真正需要时(例如所有P都有可运行的G,但当前却没有空闲的M可用)才会创建新的M。
  • 全局变量runtime.GOMAXPROCS控制的是P的数量(默认等于CPU核心数),它既不限制M的数量,更不限制G的数量上限。

为什么M不固定绑G,却能避免频繁上下文切换

这里需要分清两种切换的代价。M是OS线程,线程间的上下文切换由内核完成,代价高昂。而G是用户态的协程,其切换完全在runtime内部完成,只需要保存和恢复几个寄存器和栈指针,开销微乎其微。

调度器的设计巧妙地利用了这一点:它让每个M尽量从自己绑定的P的本地队列中获取G来执行。这种设计带来了两个显著好处:

立即学习“go语言免费学习笔记(深入)”;

  • 本地队列访问无锁,减少了竞争开销。据统计,超过90%的G调度都走这条“快速通道”,效率极高。
  • 当某个M的本地队列空了,它不会闲着,而是会去全局队列“捞”任务,或者从其他P的本地队列尾部“偷”走一半的G(这就是著名的work-stealing算法)。这既保证了执行的局部性,又实现了高效的负载均衡。
  • 此外,一个名为sysmon的系统监控线程会定期检查,如果发现某个G运行时间过长(默认超过10ms),就会通过栈抢占(stackPreempt)强制将其切走,防止它“饿死”其他G。

系统调用阻塞时,P怎么不被卡住

这是GMP模型区别于传统N:1协程模型的核心优势。在简单的N:1模型中,一旦一个协程发起阻塞式系统调用,整个线程都会被挂起,导致其他协程也无法执行。

而GMP的处理方式则聪明得多:当一个G发起阻塞式系统调用(比如read())时,它所在的M会与当前绑定的P解绑,P会被释放出来,交给其他空闲的M使用。发起调用的M则会带着这个G,单独进入阻塞状态等待系统调用返回。

调用返回后,情况分为两种:

  • 如果此时能立刻找到一个空闲的P,那么这个M就会重新绑定一个P,继续执行刚才的G。
  • 如果所有P都处于忙碌状态(拿不到P),那么这个G会被放入全局队列,等待未来任意一个M+P的组合来“捞”走它执行。

整个过程,P始终不会被阻塞,其他M的资源也不会被浪费。所以,即使程序中有上万个G在等待磁盘I/O,CPU依然能够被计算密集型的G跑满,资源利用率极高。

需要警惕的是,runtime.LockOSThread()是一个例外。它会强制将当前G与M绑定,并独占一个P。此时如果G发生长时间阻塞,它所占用的P就彻底“废”了,无法被调度器复用,因此必须谨慎使用。

什么时候GMP反而会拖慢性能

GMP虽好,但并非银弹。在以下几种场景下,如果使用不当,反而可能踩坑:

  • 大量短命Goroutine:比如为每个HTTP请求都单独启动一个go handle(),但handle函数内部全是同步计算,瞬间就结束了。这会导致频繁的G创建、销毁和调度,开销可能比直接在当前goroutine中串行执行还要大。
  • P的数量设置不当:将GOMAXPROCS设置得远高于物理核心数(比如在64核机器上设为256)。过多的P会导致更频繁的work-stealing和全局队列争抢,反而可能降低整体吞吐量。
  • 滥用LockOSThread导致M泄漏:使用了runtime.LockOSThread()却忘记配对调用UnlockOSThread(),会导致M被永久占用。当泄漏的M数量达到runtime.SetMaxThreads设置的上限(默认10000)时,新的G将无法被调度。
  • Channel使用成为瓶颈:大量goroutine在同一个channel上进行密集的收发操作,它们会在channel的sudog链表里排队,实际上变成了串行处理。这是程序设计问题,与GMP调度器本身无关。

说到底,真正影响性能的从来不是Goroutine的绝对数量,而是它们的阻塞模式、P之间的负载是否均衡,以及M资源是否被非必要地独占。这些微观细节,往往需要在pprof工具的goroutinethreadcreate性能剖析报告中才能看得真切。

来源:https://www.php.cn/faq/2411094.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

Sublime搭建个人博客静态网页生成器_集成Hugo部署与模板编辑插件
编程语言
Sublime搭建个人博客静态网页生成器_集成Hugo部署与模板编辑插件

Sublime Text 能当 Hugo 静态站点编辑器用吗? Sublime Text 能不能直接当 Hugo 静态站点编辑器用? 答案是肯定的,但别指望它能“开箱即用”。Sublime Text 本质上是一个强大的文本编辑器,它本身并不集成 Hugo 的运行时环境,也没有模板热编译这类功能。它的

热心网友
05.03
Go高性能缓冲IO中bufio包的使用小结
编程语言
Go高性能缓冲IO中bufio包的使用小结

bufio Reader:高效读取数据 说到高效读取,bufio Reader绝对是主力。它本质上是对io Reader的一层智能封装,内部自带一个缓冲区。这个缓冲区的妙处在于,它能从底层数据源(比如文件或网络连接)中“批发”式地读取一大块数据,暂存起来,而不是每次读取都去麻烦操作系统。这样一来,频

热心网友
05.03
Sublime Text怎么快速打开文件_Sublime Text Goto Anything文件跳转教程【基础】
编程语言
Sublime Text怎么快速打开文件_Sublime Text Goto Anything文件跳转教程【基础】

Sublime Text 的 Ctrl+P 无反应?别急,先排查这几个隐形门槛 在 Sublime Text 里,Ctrl+P(Windows Linux)或 Cmd+P(macOS)这个快捷键,堪称文件跳转的“王牌”。但有时候,按下快捷键却毫无反应,问题往往不在于功能本身失效,而是一些容易被忽略的

热心网友
05.03
Atom怎么配置Go语言?Atom搭建Go开发环境教程
编程语言
Atom怎么配置Go语言?Atom搭建Go开发环境教程

Atom怎么配置Go语言?Atom搭建Go开发环境教程 先说一个核心判断:Atom编辑器已经停止维护,其go-plus插件虽然在较新版本(v1 60+)上还能运行,但诸如跳转、补全等核心功能,严重依赖早已被官方弃用的godef或guru工具。实际体验与现代工具链相比,差距悬殊。如果你的目标只是高效地

热心网友
05.03
如何在 Go 中实现对 API 接口的幂等性校验
编程语言
如何在 Go 中实现对 API 接口的幂等性校验

如何在 Go 中实现对 API 接口的幂等性校验 为什么直接用 uuid 作为幂等键会出问题 不少开发者第一步就想当然地让前端传一个 idempotency-key,比如直接用 uuid New() 生成,后端存进 Redis 并设置 TTL,请求来了先查是否存在。这套路听起来挺合理,对吧?但实际踩

热心网友
05.03

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

元旦节一日游
职业与学业
元旦节一日游

元旦一日游:在科技与自然的交汇处漫步 新年的钟声犹在耳畔,2026年的第一个假日便已翩然而至。空气中弥漫着喜庆与松弛的气息,我也决定暂别日常的节奏,加入这人潮涌动的假日行列,来一场计划之外的短途游览。 中午时分,目的地准时抵达。眼前是人头攒动的热闹景象,那份跃跃欲试的心情几乎要破笼而出。不过,一切还

热心网友
05.03
今天元旦
职业与学业
今天元旦

今天元旦 元旦这天,大概是孩子们最快乐的时刻了。你听,大清早的鞭炮声就此起彼伏,宣告着新年的到来。一句“新年快乐”,是这一天最自然而然的开场白。 说到新年,怎么能少得了饺子呢?这几乎是家家户户的保留节目。一家人早早地忙活起来:爸爸负责擀皮,妈妈和我负责包。分工明确,配合默契,不一会儿,一排排白胖胖的

热心网友
05.03
欢庆元旦
职业与学业
欢庆元旦

又是一个阳光明媚、万&里无云的好天气 处处弥漫着一股喜气洋洋的气氛,偶尔会有一丝丝凉风拂过脸上抑制不住的笑容。你知道吗?全校师生正齐聚一堂,准备欢庆元旦呢! 活动伊始,场内还有些许嘈杂的声响,但随着几位英姿飒爽的主持人登场,现场顷刻间鸦雀无声,所有人的目光都聚焦在舞台上,专心致志地等待节目开始。 精

热心网友
05.03
元旦运动会
职业与学业
元旦运动会

光阴似箭,一转眼2026就要和我们说再见了 在年末的最后一天,我们学校举办了一场气氛热烈的运动会,为这一年画上了一个充满活力的句号。 比赛开始了 各项赛事紧锣密鼓地展开,同学们个个摩拳擦掌,做好了充分的赛前准备。首先登场的是我个人最喜欢也最拿手的项目——跳绳。裁判员的口哨声清脆响起,我手中的绳子便立

热心网友
05.03
弘扬核心价值观演讲稿
职业与学业
弘扬核心价值观演讲稿

践行核心价值观演讲稿 本站为您整理了一系列关于践行社会主义核心价值观的演讲稿,供您参考。更多相关文章,敬请关注本栏目。 【践行核心价值观演讲稿(一)】 尊敬的老师,亲爱的同学们: 大家好。我是来自第四小学五(1)班的钟李敏。今天,我想和大家分享的主题是《弘扬核心价值观,争当苏区好少年》。 还记得每天

热心网友
05.03