千家信息网

Go语言中goroutine的调度原理是什么

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,Go语言中goroutine的调度原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、关于并发的基础知识在讲go
千家信息网最后更新 2026年11月01日Go语言中goroutine的调度原理是什么

Go语言中goroutine的调度原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

一、关于并发的基础知识

在讲goroutine的调度原理之前,有些与操作系统相关的知识,我们需要先知道,例如:

1.什么是并发?

并发:两个或两个以上的任务在一段时间内被执行。我们并不关心这些任务是否在同一时刻执行,我们只是知道,这些任务在这一段时间能能够都被执行,当然这一段时间可以很长,也可以很短。

2.并发的最小并发单位是什么?

进程是计算机资源分配最小的单位,是CPU分配资源的基本单位,具有独立的内存。

线程是计算机调度最小的单位,也是程序执行的最小单位,是在进程中的,一个进程往往会有一个到多个线程。

3.计算机是如何实现并发的?

计算机的分时调用是并发的根本,CPU通过快速的切换作业来执行不同的作业,基本的调度单位在执行的时候可以被阻塞掉,此时就会将CPU资源让出来,等到该调度单位再次被唤醒的时候,又可以使用CPU资源,而操作系统保证了整个的调度过程。

二、Goroutine的基础知识

除此之外,关于goroutine的调度原理,我们需要弄清楚下面几个问题。

1.goroutine是什么?

Goroutine:是Go里的一种轻量级线程--协程。

1)相对线程,协程的优势就在于它非常轻量级,进行上下文切换的代价非常的小。

2)对于一个goroutine ,每个结构体G中有一个sched的属性就是用来保存它上下文的。这样,goroutine 就可以很轻易的来回切换。

3)由于其上下文切换在用户态下发生,根本不必进入内核态,所以速度很快。而且只有当前goroutine 的 PC, SP等少量信息需要保存。

4)在Go语言中,每一个并发的执行单元为一个goroutine。

Go 语言中的goroutine并发, 采用的是CSP(communicating sequential processes)并发模型,讲究的是以通讯的方式来进行数据共享,是通过goroutine配合channel的方式来实现的。(备注:这部分知识后续单独整理一章。)

2.既然它是比线程还小的粒度,那么它与线程有什么关系?

Go语言的线程模型就是一种特殊的两级线程模型,如下所示:

两级线程模型的实现非常复杂,和内核级线程模型类似,一个进程中可以对应多个内核级线程,但是进程中的线程不和内核线程一一对应;这种线程模型会先创建多个内核级线程,然后用自身的用户级线程去对应创建的多个内核级线程,自身的用户级线程需要本身程序去调度,内核级的线程交给操作系统内核去调度。

三、Goroutine的调度策略

我们先来看下,Go线程实现了MPG模型:

S(Sched):结构就是调度器,它维护有存储M和G的队列以及调度器的一些状态信息等。

M(Machine):一个M直接关联了一个内核线程。

P(processor):代表了M所需的上下文环境,也是处理用户级代码逻辑的处理器。G(Goroutine):其实本质上也是一种轻量级的线程。

它们的关系如下所示:

介绍:

一个M会关联两个东西,一个是内核线程,一个是可执行的进程。

一个上下文P会有两类Goroutine,一类是正在运行的,图中的蓝色G;一类是正在排队的,图中灰色G,这个会存储在该进程中的runqueue里面。

这里的上下文P的数量也表示的是Goroutinue运行的数量,一般设置为几个,机器中就会并发运行几个。当然这里P的数量是可以设置的,通过环境变量GOMAXPROCS的值,或者通过运行时调用函数runtime.GOMAXPROCS()进行设置,最大值是256。

有了上面的知识,我们知道了Goroutine的一些基本概念,但是我们还是不知道,Go的并发是如何调度的。而这一个话题,就需要我们将Goroutine的几种场景(创建、销毁和运行)做拆分。

1.在执行go语句之前,我们看下程序都做了哪些准备,也就是程序的初始化启动流程是什么样子的?

上面的代码,有三个点非常关键,分别是runtime.schedinit,runtime.main,runtime.mstart

Step1: runtime.schedinit:这一步是调度器的初始化操作,它会设置GOMAXPROCS的大小,这里的大小不能超过它的上限256,并创建设置好对应数量的P,当然这些P都处于闲置状态;然后,将这些创建好的P都存放到sched中pidle所关联的闲置列表中。

Step2: 程序会继续执行runtime.newproc来创建程序的第一个goroutine,而这个goroutine会执行runtime.main也就是我们看到的main函数,在这之后main会主动创建一个内核线程M,这个M只用来做系统监控用,这个内核线程与程序中goroutinue的调度有关系。

Step3:在runtime.mstart之后,程序就开始执行了,如果后续需要创建goroutine,就会调用go语句来创建。

2.goroutine创建流程是什么样子的?

在调用go func()的时候,会调用runtime.newproc来创建一个goroutine,这个goroutine会新建一个自己的栈空间,同时在G的sched中维护栈地址与程序计数器这些信息(备注:这些数据在goroutine被调度的时候会被用到。准确的说该goroutine在放弃cpu之后,下一次在重新获取cpu的时候,这些信息会被重新加载到cpu的寄存器中。)

创建好的这个goroutine会被放到,它所对应的内核线程M所使用的上下文P中的runqueue中。等待调度器来决定何时取出该goroutine并执行,通常调度是按时间顺序被调度的,这个队列是一个先进先出的队列。

3.新建的这些goroutine是如何被调度的呢?

goroutine在创建好了之后,调度器会决定何时执行这个goroutine,这个过程就叫做调度。

新建好的goroutine,最开始都会存储在某一个线程M,所关联的上下文P的runqueue中,但是在后续的调度中,有些goroutine因为调用了runtime.gosched,会被放到全局队列中。

线程M的选择过程,按照下面的顺序执行:

1.从M对应的P中的runqueue中取出goroutine,来执行,没有的话,执行2。

2.从全局队列里面尝试取出一个goroutine来执行,有的话,执行!没有的话,执行3。

3.从其他的线程M的P中,偷出一些goroutine来执行,偷失败了,执行4。(备注:这里偷的话,一偷就偷一半,使用的算法叫做work stealing。)

4.线程M发现无事可做,就去休息了,也就是线程的sleep,它等待被唤醒。

4.运行中的goroutine是怎么停止的呢?一旦被停止了的话,那排队在它后面的goutinue该怎么办?

讲完了goroutine的调度之后,我们便要考虑一个问题,正在被执行的goroutine何时停止,停止了之后会发生什么?而挂在M对应的P后面的runqueue中的goroutine该怎么办?

情况1:runtime·park

当调用了runtime·park函数之后,goroutine会被设置成waiting状态,线程M会放弃它自身关联的上下文P,而系统会分配一个新的线程M1来接管这个上下文P,(备注:当然这里面的M1也有可能是本来就创建好的,处于闲置状态中的)。

原来的线程M0则会与上下文断开连接,M0因为无事可做,就去sleep了,等待下次被唤醒。如下图所示:

channel的读写操作,定时器中,网络poll等都有可能park goroutine。

情况2:runtime·gosched

调用runtime·gosched函数也可以让当前goroutine放弃cpu,这种情况下会将goroutine设置成runnable,放置到全局队列中。备注:这个也就是为什么全局变量的queue里面会有goroutine的原因。

5.goroutine被唤醒之后,会做什么?

goroutine处于waiting状态的话,在调用runtime·ready函数之后,会被唤醒,唤醒的goroutine会被重新放到,M对应的上下文所对应的runqueue中,等待被调度。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

线程 调度 内核 上下 上下文 程序 单位 模型 进程 知识 队列 运行 函数 备注 时候 状态 系统 关联 语言 最小 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州大一互联网络科技有限公司 苏州找大状互联网科技有限公司 中国互联网科技工作委员会毛军 科技创新与互联网经济 中资互联网科技 为想互联网科技 嘟嘟瓜互联网科技 西安互联网科技公司 互联网科技上市公司 新华互联网科技2019 北京大学互联网科技怎么样 中国的互联网科技企业的崛起 互联网科技扶贫时间 华夏恒生科技与互联网科技 江苏苏星互联网科技有限公司 工业互联网科技成果转化 济南小医互联网科技有限公司招聘 上海万顺科技互联网有限公司招聘 北京品多多互联网科技有限公司 东风日产互联网科技公司叫什么 花魁咖啡 睿民互联网科技 互联网巨头投资的硬核科技 伊宁互联网科技做什么的 互联网第三次科技革命特征 广东工业互联网大赛深圳学泰科技 城市宝互联网科技有限公司 易企秀互联网科技是做什么的 容联科技互联网电商 广州三三互联网科技有限公司
0