GO学习之 goroutine的调度原理
Go语言的goroutine是由Go运行时的调度器进行调度管理的。Go的调度器采用了协同式调度(G-P-M模型),其中G表示goroutine,P表示processor(处理器),M表示machine(线程)。
调度器的主要工作原理如下:
- 当一个M线程启动时,它会在自己的本地队列中寻找可运行的G。
- 如果本地队列为空或者本地队列长度不足,M线程会从全局运行队列中抢取G。
- 一旦M线程找到了G,它会将G绑定到自己并开始运行该goroutine。
- 当G执行了一段时间或者调用了runtime.Gosched()主动放弃CPU使用权时,M线程会将G放回到全局运行队列,然后再从队列中选择G执行。
- 如果全局队列为空,但是P列表中的处理器不足以满足需求,调度器会创建新的线程(M)来帮助处理。
下面是一个简单的例子,演示了如何创建goroutine:
package main
import (
"fmt"
"runtime"
)
func printNumbers() {
for i := 1; i <= 3; i++ {
fmt.Println(i)
}
}
func main() {
// 设置CPU核心数
runtime.GOMAXPROCS(1)
fmt.Println("Starting main go routine.")
// 创建一个goroutine
go printNumbers()
// 模拟其他工作
for i := 1; i <= 3; i++ {
fmt.Println("Doing some work in main go routine.")
}
// 确保主goroutine不会提前退出
var input string
fmt.Scanln(&input)
}
在这个例子中,我们创建了一个goroutine来执行printNumbers
函数,并通过runtime.GOMAXPROCS(1)
设置了运行时的CPU核心数为1,以保证在单核心环境中能清晰地观察到调度的行为。
评论已关闭