Open wtysos11 opened 3 years ago
G可以看作是执行的协程,M是一个操作器(可以看作与内核线程对应)
G被放在一个全局的等待队列上,M每次会从这个队列中获取协程进行执行。 问题:
G:goroutine,运行的函数指针,代表一个用户代码的执行流,数量没有限制。
P:processor,上下文,大小默认为机器核数(逻辑核),表示执行所需的资源
M:machine,比P多,一般不会多太多。代表执行者,底层线程
局部队列:G不再只是放在全局的等待队列中,每个P都有一条自己的队列。新的G会放入到P对应的队列中,满了之后再放入到全局队列内。
抢占:work stealing,如果某个P的队列为空(协程全部被执行完),则该协程会从全局队列中获取G;如果全局队列也是空的,则会从其他P的队列中获取G(好像是一半)
当G因为网络或者锁等需要切换,则G和M分离,M通过调度执行新的G
当M因为系统调用或者cgo阻塞,sysmon会将P与M分离,由其他M结合P来进行调度。
调度:golang调度的职责就是为需要执行的Go协程G寻找执行者M以及执行的准许和资源P。并没有一个调度机的尸体,调度是需要发生调度时由m执行runtime.shedule方法进行的
调度实际
Golang 的 goroutine 是如何实现的? - 腾讯技术工程的回答 - 知乎 https://www.zhihu.com/question/20862617/answer/921061289
协程的基础:#217 Go风格协程库