Golang GMP

GMP

G:goroutine

M:machine(thread)

P:processor

全局队列: 存放等待运行的G。

P的本地队列:存放等待运行的G, 有数量限制,优先将新创建的G放在P的本地队列中,如果满了放在全局队列中。

P列表:程序启动时创建,最多有GOMAXPROCS个(可设置)。

M列表:当前操作系统分配到当前Go程序的内核线程数。

P的数量可通过:1.环境变量 $GOMAXPROCS,2.在程序中通过runtime.GOMAXPROCS()来设置

M的数量可通过: runtime/debug包中的SetMaxThreads函数来设置,Go语言本身设定M的最大量是10000,一般忽略。有一个M阻塞,会创建一个新的M,有一个M空闲,会回收或者睡眠。

调度器的设计策略:

1.复用线程: work stealing机制【P已经将G全部执行完,然后去查询全局队列,全局队列中也没有G,而另一个M中除了正在运行的G外,队列中还有3个G待运行。此时,空闲的P会将其他P中的G偷取一部分过来,一般每次偷取一半。】,hand off机制【当本线程M0因为G0进行系统调用阻塞时,线程释放绑定的P,把P转移给其他空闲的线程执行。 进而某个空闲的M1获取P,继续执行P队列中剩下的G。 而M0由于陷入系统调用而进被阻塞,M1接替M0的工作,只要P不空闲,就可以保证充分利用CPU。 M1的来源有可能是M的缓存池,也可能是新建的。】

2.利用并行

3.抢占

4.全局G队列

posted @ 2022-02-19 15:26  sqdtss  阅读(186)  评论(0编辑  收藏  举报