面试题答案
一键面试G(Goroutine)
- 含义:代表一个协程,是Go语言中实现并发的基本单位。每个Goroutine都是一个独立的执行单元,有自己的栈空间、程序计数器等。
- 作用:允许程序在一个线程内实现多个并发任务。一个Goroutine可以认为是一个轻量级的线程,它的创建和销毁开销极小,使得Go语言可以轻松创建成千上万的并发任务。
M(Machine)
- 含义:代表操作系统线程,是Go语言运行时与操作系统线程的映射。每个M都对应一个真实的操作系统线程。
- 作用:负责执行Goroutine。M从P的本地队列或者全局队列中获取Goroutine,并执行其代码。M还负责处理系统调用等与操作系统交互的操作。
P(Processor)
- 含义:代表处理器上下文,它包含了运行Goroutine所需要的资源,如Goroutine队列等。P的数量决定了同一时刻可以并发执行的Goroutine数量(逻辑上的并发)。
- 作用:它管理着一个本地的Goroutine队列,M需要绑定到P才能执行Goroutine。P还负责调度Goroutine,从本地队列或者全局队列中选择Goroutine交给M执行。
协同工作机制
- 创建与调度:当创建一个新的Goroutine时,它会被放入某个P的本地队列。如果本地队列满了,会被放入全局队列。
- M与P的绑定:M会尝试绑定到一个P,获取P本地队列中的Goroutine来执行。如果本地队列为空,M会从全局队列或者其他P的队列中偷取Goroutine来执行。
- 系统调用处理:当M执行的Goroutine发生系统调用时,M会阻塞,此时P会与M解绑,寻找其他空闲的M来执行队列中的Goroutine。当系统调用完成,原来的Goroutine会被重新放入队列等待执行。
不同场景下的协同工作变化举例
- 高CPU密集型场景:假设存在大量计算任务的Goroutine。此时,P的数量有限,M会持续执行这些Goroutine,由于计算任务多,很少发生系统调用,M与P绑定紧密,高效利用CPU资源。例如一个复杂的数学计算程序,多个Goroutine并行计算不同部分。
- 高I/O密集型场景:若有许多网络请求等I/O操作的Goroutine。当某个Goroutine进行I/O操作时,对应的M会阻塞,P会迅速与M解绑,将其他Goroutine分配给其他空闲的M执行,充分利用系统资源。比如一个爬虫程序,多个Goroutine同时发起网络请求获取网页内容。