Goroutine 的调度

xiaoxiao2021-02-28  108

结构——M, P, S

Go的调度器内部有三个重要的结构:M,P,S:

M: 内核OS线程 G: 一个goroutine,它有自己的栈,instruction pointer和其他信息(正在等待的channel等等),用于调度。 P: 代表调度的上下文,可以把它看做一个局部的调度器,使go代码在一个线程上跑,它是实现从N:1到N:M映射的关键。 (P的数量可以通过GOMAXPROCS()来设置,它其实也就代表了真正的并发度,即有多少个goroutine可以同时运行。)

灰色的G在等待执行。。。

线程阻塞——投奔其他线程

图中看到,当一个OS线程M0陷入阻塞时,P转而在OS线程M1上运行。调度器保证有足够的线程来运行所以的context P。

当MO返回时,它必须尝试取得一个context P来运行goroutine,一般情况下,它会从其他的OS线程那里steal偷一个context过来,如果没有偷到的话,它就把goroutine放在一个global runqueue里,然后自己就去睡大觉了(放入线程池里)。Contexts们也会周期性的检查global runqueue。

分配不均——steal work

global runqueue——P 会周期性检查global runqueue;其他的P——偷一半去执行;


reference

https://www.zhihu.com/question/20862617

转载请注明原文地址: https://www.6miu.com/read-66570.html

最新回复(0)