MST

星途 面试题库

面试题:Go语言Goroutine调度器的GMP模型细节

详细阐述Go语言Goroutine调度器GMP模型中G、M、P各自的含义、作用以及它们之间是如何协同工作来实现高效并发调度的?请举例说明在不同场景下,这种协同工作的变化。
34.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

G(Goroutine)

  1. 含义:代表一个协程,是Go语言中实现并发的基本单位。每个Goroutine都是一个独立的执行单元,有自己的栈空间、程序计数器等。
  2. 作用:允许程序在一个线程内实现多个并发任务。一个Goroutine可以认为是一个轻量级的线程,它的创建和销毁开销极小,使得Go语言可以轻松创建成千上万的并发任务。

M(Machine)

  1. 含义:代表操作系统线程,是Go语言运行时与操作系统线程的映射。每个M都对应一个真实的操作系统线程。
  2. 作用:负责执行Goroutine。M从P的本地队列或者全局队列中获取Goroutine,并执行其代码。M还负责处理系统调用等与操作系统交互的操作。

P(Processor)

  1. 含义:代表处理器上下文,它包含了运行Goroutine所需要的资源,如Goroutine队列等。P的数量决定了同一时刻可以并发执行的Goroutine数量(逻辑上的并发)。
  2. 作用:它管理着一个本地的Goroutine队列,M需要绑定到P才能执行Goroutine。P还负责调度Goroutine,从本地队列或者全局队列中选择Goroutine交给M执行。

协同工作机制

  1. 创建与调度:当创建一个新的Goroutine时,它会被放入某个P的本地队列。如果本地队列满了,会被放入全局队列。
  2. M与P的绑定:M会尝试绑定到一个P,获取P本地队列中的Goroutine来执行。如果本地队列为空,M会从全局队列或者其他P的队列中偷取Goroutine来执行。
  3. 系统调用处理:当M执行的Goroutine发生系统调用时,M会阻塞,此时P会与M解绑,寻找其他空闲的M来执行队列中的Goroutine。当系统调用完成,原来的Goroutine会被重新放入队列等待执行。

不同场景下的协同工作变化举例

  1. 高CPU密集型场景:假设存在大量计算任务的Goroutine。此时,P的数量有限,M会持续执行这些Goroutine,由于计算任务多,很少发生系统调用,M与P绑定紧密,高效利用CPU资源。例如一个复杂的数学计算程序,多个Goroutine并行计算不同部分。
  2. 高I/O密集型场景:若有许多网络请求等I/O操作的Goroutine。当某个Goroutine进行I/O操作时,对应的M会阻塞,P会迅速与M解绑,将其他Goroutine分配给其他空闲的M执行,充分利用系统资源。比如一个爬虫程序,多个Goroutine同时发起网络请求获取网页内容。