当前位置:  首页>> 技术小册>> GO面试指南

在 Go 语言中,每个 goroutine 都会被分配一个固定的时间片,当时间片用完后,调度器会暂停当前 goroutine,切换到其他 goroutine 上执行。这种机制被称为抢占式调度,因为调度器可以在任何时候抢占当前 goroutine 的执行,并将 CPU 时间片分配给其他 goroutine。

抢占式调度有以下几个特点:

  • 并发执行:多个 goroutine 可以同时执行,彼此独立,互不干扰。
  • 非确定性:由于调度器会在任何时候抢占当前 goroutine,因此程序的执行顺序不是确定的。
  • 公平性:调度器会公平地分配 CPU 时间片,以确保每个 goroutine 都有机会被执行。

下面是一个示例代码,演示了抢占式调度的效果:

  1. package main
  2. import (
  3. "fmt"
  4. "runtime"
  5. )
  6. func main() {
  7. runtime.GOMAXPROCS(1) // 限制只使用一个 CPU 核心
  8. go func() {
  9. for i := 0; i < 10; i++ {
  10. fmt.Println("goroutine 1:", i)
  11. }
  12. }()
  13. go func() {
  14. for i := 0; i < 10; i++ {
  15. fmt.Println("goroutine 2:", i)
  16. }
  17. }()
  18. // 等待 goroutine 执行完毕
  19. var input string
  20. fmt.Scanln(&input)
  21. }

在上面的示例代码中,我们通过调用 runtime.GOMAXPROCS(1) 来限制程序只使用一个 CPU 核心。然后我们启动了两个 goroutine,分别打印数字,由于只有一个核心,所以两个 goroutine 会交替执行,输出结果可能类似于下面这样:

  1. goroutine 1: 0
  2. goroutine 1: 1
  3. goroutine 2: 0
  4. goroutine 1: 2
  5. goroutine 2: 1
  6. goroutine 1: 3
  7. goroutine 2: 2
  8. goroutine 1: 4
  9. goroutine 2: 3
  10. goroutine 1: 5
  11. goroutine 2: 4
  12. goroutine 1: 6
  13. goroutine 2: 5
  14. goroutine 1: 7
  15. goroutine 2: 6
  16. goroutine 1: 8
  17. goroutine 2: 7
  18. goroutine 1: 9
  19. goroutine 2: 8
  20. goroutine 2: 9

可以看到,两个 goroutine 交替执行,输出结果不是确定的。这就是抢占式调度的特点。


该分类下的相关小册推荐: