一、协程与进程,线程的关系
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进入休眠。