前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入浅出Go调度器中的GMP模型

深入浅出Go调度器中的GMP模型

作者头像
Go学堂
发布2023-08-28 14:50:49
7500
发布2023-08-28 14:50:49
举报
文章被收录于专栏:Go工具箱Go工具箱

大家好,我是渔夫子。

今天给大家介绍一下Go协程调度器的G-M-P的模型,以及一个线程在该模型下是如何被调度的。

在现代操作系统中,分配资源的基本单位是进程。而在进程中,独立运行和调度的基本单位是线程。但是,在Go语言中,执行和调度的基本单位是协程。为了更高效的执行协程,Go语言实现了自己的协程调度模型

我们通过下面的一段简单代码来帮助你更好的理解Go程序中的协程。

代码语言:javascript
复制
for i := 0; i < 4; i++ {
        go func() {
                time.Sleep(time.Second)
        }()
}
fmt.Println(runtime.NumGoroutine())

上述代码最终输出结果是 5。也就是说在这段代码中启动了5个协程。但这里的问题是,这5个协程并不能直接向操作系统申请运行资源(CPU、内存等),而是必须要被分配给内核态下的线程才能执行,也就是说要依赖于操作系统级别的线程调度模型才行。根据用户级线程和内核级线程之间的对应关系,有三种模型:1对1N对1M对N。以上5个goroutine是如何分布在内核级线程上的?这是由Go的goroutine调度程序决定的。

GMP模型

在Go语言中,协程调度器是基于G-M-P模型实现的。

  • G:代表协程
  • M:操作系统下内核态的线程。在Go中能支持的最大线程数量是10000个,但一般情况下不会创建这么多线程。
  • P:处理器,可以把它理解为这时候一个等待被分配给M的协程队列。P的数量一般通过参数runtime.GOMAXPROCS设定。

下面是一个1个M只绑定1个P的关系模型。如下图:

协程被执行的流程(goroutine tour)

在代码中,当通过代码 go func(){}启动一个协程后,GMP是如何工作的呢?下图详细解释了GMP是如何调度协程的。

  1. 首先是创建新的协程
  2. 如果在本地的队列中有足够的空间,则会直接进入本地队列等待M的执行;如果本地队列已经满了,则进入全局队列(在GMP模型中,所有的M都可以从全局队列中获取协程并执行)
  3. 协程必须在M上才能执行,M和P是一对一的绑定关系,如果在M绑定的P中存在可以执行的G,则从P中拉出G来执行;如果P为空并且不存在可执行的G,则M从全局队列中取出G;如果全局队列也是空的,则从另一个P中提取G。
  4. 为G的运行分配必要的资源,并等待CPU对其进行调度。
  5. 分配CPU资源,并执行 func(){} 函数。

调度策略

对于goroutine调度器来说最重要的调度策略是:重用,避免频繁的资源创建和破坏,最大限度地提高系统吞吐量和并发性。这是操作系统进行线程调度的最终目标。重用也是许多“池技术”的基础。围绕这一原则,goroutine调度器通过以下方式优化调度策略:

  1. 工作队列窃取机制:当线程 M 空闲时,会从其他的繁忙的队列P中”窃取“任务G来执行,而不是销毁空闲的线程 M。因为线程的创建和销毁都会消耗系统资源,避免频繁的创建线程和销毁线程可以打打提高系统的并发性。
  2. 切换机制:当一个线程M被阻塞时,M会主动将P切换到另一个空闲的M。

此外,在go的1.14版本中,go语言技术团队试图向调度器中添加可抢占技术,具体可参考:https://github.com/golang/go/issues/24543

原始的MG模型

在Go语言早期,协程调度器模型并不是G-M-P,而是G-M模型。整个调度器就只有一个全局的等待队列G,同时所有的M都从全局的队列中获取协程G来执行。该模型最初应用于go1.1版本,后来被现在的G-M-P模型给替代,即加入了协程的本地队列。增加P的原因如下:

  1. 不同的M从全局带执行协程队列中获取要执行的协程时,需要加锁。锁的粒度越大,就限制系统并发能力的改进。
  2. 如果没有本地队列,当线程执行IO密集型操作时,M会阻塞IO操作,并且相应的G无法执行(GMP可以将G交给其他M执行),因此GM模型在处理IO密集型任务时性能较低。

总结

本文通过一个简单的协程代码,来说明协程是如何在G-M-P模型下执行的。同时还回顾了最早的G-M模型,通过分析G-M模型的缺点,说明引入P的优越性。

原文地址:https://www.sobyte.net/post/2023-03/gpm/#goroutine-tour

别说明:你的关注,是我写下去的最大动力。点击下方公众号卡片,直接关注。关注送《100个go常见的错误》pdf文档、经典go学习资料。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-05-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Go学堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • GMP模型
  • 协程被执行的流程(goroutine tour)
  • 调度策略
  • 原始的MG模型
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档