Go 并发编程面试题, 请介绍 Go Scheduler 的初始化过程?
Go 并发编程面试题, 请介绍 Go Scheduler 的初始化过程?
QA
Step 1
Q:: Go Scheduler 的初始化过程是怎样的?
A:: Go Scheduler 的初始化过程包括以下步骤:
1. 系统启动时会初始化 P (Processor)
,数量等于 GOMAXPROCS 值,默认为 CPU 核数。
2.
为每个 P 创建一个本地队列用于存储待执行的 Goroutine。
3.
主线程会创建一个全局运行队列用于存放新建但无 P 可用的 Goroutine。
4. 初始化所有的 M (Machine)
,即操作系统线程,并将其与 P 绑定。
5.
Scheduler 开始运行,根据全局队列和本地队列的情况,分配 Goroutine 给不同的 M 执行。
Step 2
Q:: Go Scheduler 是如何处理抢占调度的?
A:: Go Scheduler 使用了多种机制来实现抢占调度:
1. Goroutine 的运行时间超过了设定的时间片(10
ms),调度器会尝试将该 Goroutine 标记为被抢占。
2.
调度器还会在 Goroutine 的函数调用、系统调用或垃圾回收点等时机插入检查点,以确保它不会长期占用 CPU。
3.
当一个 Goroutine 被标记为被抢占时,它将在下次返回调度器时被强制调度。
Step 3
Q:: Go Scheduler 如何处理全局队列和本地队列的平衡?
A:: Go Scheduler 通过 'work stealing'
机制来平衡全局队列和本地队列:
1.
当一个 P 的本地队列为空时,它会尝试从全局队列中偷取一个 Goroutine 来执行。
2.
如果全局队列也为空,P 会尝试从其他 P 的本地队列中偷取一半的 Goroutine。
3.
通过这种方式,Go Scheduler 保证了所有 P 都能保持忙碌,从而提高系统的吞吐量。
Step 4
Q:: GOMAXPROCS 的作用是什么?
A:: GOMAXPROCS 是 Go 语言运行时用于限制并发处理的一个重要参数。它决定了系统中可以并行运行的最大操作系统线程数(即 P 的数量)。
当 GOMAXPROCS 设置较小时,系统中的 Goroutine 会在有限的线程之间调度执行,可能会出现阻塞等待的情况;而设置较高的 GOMAXPROCS 则可以提高并行度,但也可能导致上下文切换开销增大。