GMP
总述
GMP 模型
- G(Goroutine):表示一个 Goroutine,包含栈和相关上下文信息。
- M(Machine):表示一个执行线程,负责将 Goroutine 映射到操作系统的线程上。每个 M 都有自己的调用栈和寄存器状态。(数量是动态的,由调度器决定,根据当前负载动态变化,默认为 10000)
- P(Processor):表示一个逻辑处理器,维护一个处于可运行状态的Goroutine 队列,每个 M 都和一个 P 有关。(数量是固定的)
特点
- 抢占式协调:在协程中需要一个协程主动让出 CPU 下一个协程才能使用 CPU, 而 Goroutine 规定一个 Goroutine 每次最多只能占用 10ms 的 CPU,然后就要切换到下一个, 防止其他协程长时间不被执行。
- 复用线程:Go 语言的调度器会复用线程,而不是每次都创建新的线程,这样可以减少线程创建和销毁的开销,提高性能。
- 工作偷取(Work stealing):当
M
没有可运行的G
时,会尝试从其他线程绑定的P
的本地队列中偷取一半的G
来运行,而不是销毁M
。 - 挂起机制(Hand off):当
G
由于系统调用而阻塞时,M
会释放绑定的P
供其他M
使用 - 并行:通过
GOMAXPROCS
配置P
的数量,从而实现并行执行,P
的数量决定了并行度,P
的数量等于 CPU 核数时,可以实现最大并行度。
结构
全局队列:是存放所有正在等待的 G。
本地队列:存放当前 P 的 G,每个 P 都有一个队列,用于存放当前的 P 等待和正在运行的 G,最大数量为 256 个。
二者之间的关系(偷取机制)
- 只有本地队列满了,才会存放在全局队列中
- 如果一个本地队列为空,那么他会从其他的本地队列获取一半到自己的本地队列中。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 !