3

深入理解 Go | 调度:GMP 模型(第三部分)

 2 years ago
source link: https://ictar.github.io/2020/04/14/dive-into-go-schedule-gpm-part3/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

深入理解 Go | 调度:GMP 模型(第三部分)

发表于

2020-04-14 更新于 2021-01-26

阅读次数: 43 Disqus: 0 Comments

以下基于 Go 1.14

Go 程序中,在下面几种情况下都有可能触发调度(即调用 runtime.schedule()): * 创建一个新的线程时 * goroutine 执行结束的时候 * 主动挂起 * 协作式调度 * 基于函数调用的抢占式调度 * 基于信号的抢占式调度(Go 1.14 新特性) * 系统调用

前面已经提到过前面两种,下面看下其他几种情况的行为方式。

当有诸如 time.Sleep()、锁、channel 之类的操作时,就会主动挂起 goroutine。而 goroutine 的主动挂起和唤醒分别是通过 runtime.gopark()runtime.goready() 实现的:

不是所有的系统调用都会触发调度,只有那些需要运行时参与的系统调用(syscall.Syscall())才有可能触发调度:

协作式调度

协作式调度指的是 goroutine 主动让出处理器,从而允许其他 goroutine 运行:

抢占式调度

Go 语言的抢占式调度是在分段栈的机制上实现的。编译器会在分段栈上插入函数,这样,所有的 goroutine 在进行函数调用的时候都有机会进入运行时检查是否需要抢占。

但是,这种机制对于诸如轮询计算这种没有函数调用的 goroutine 来说,是无法抢占成功的。因此,Go 1.14 版本引入了基于信号的抢占式调度。

请言小午吃个甜筒~~

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK