golang goroutine的调度

一、协程与进程,线程的关系

1.进程:程序的一次执行过程,资源的最小分配单位

进程状态:

就绪态,运行态,阻塞态

进程调度算法:

1.)FIFO(First Input First Output 先进先出法)、

2.)RR(时间片轮转算法)

3.)(HPF)最高优先级算法。

进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,由操作系统调度。

2.线程:操作系统的最小调度单位,可并发执行,共享进程资源(相同的地址空间,共享内存,信号量等)

状态:初始化、可运行、运行中、阻塞、销毁

线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,由操作系统调度。

3.协程:轻量级线程,完全用户态控制执行,特殊的函数,降低了调度开销

协程共享堆,不共享栈,协程由程序员在协程的代码里显示调度。协程需要的栈相比线程小得多,几kb,避免了过多调度带来的消耗。

调度:M-P-G模型

G:goroutine受管理的轻量线程

M:machine等同于系统线程

P:process,M运行G需要的资源,每个P会维护一个本地的运行队列,除了每个P拥有一个本地的运行队列外,还存在一个全局的运行队列。个数取决于设置的GOMAXPROCS,默认使用最大内核数。

调度关系图如下:

   

        M得到P后执行G,取G的顺序:本地运行队列 > 全局运行队列 > 其他P的运行队列,如果所有运行队列都没有可用的G,M会归还P并进入休眠。G的数量超出了M的处理能力,并且还有空余P,runtime就会自动创建新的M;

 M0阻塞时,P会运行M1,M0返回时必须尝试获得一个P来运行goruntine,若未获得P将goruntine放入全局队列进入休眠。Goruntine阻塞时会发生上下文切换执行如下操作:

 1.)系统调用。

 2.)读写channel。

 3.)gosched主动放弃,会将G扔进全局队列, M归还P进入休眠。   

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章