go的调度机制

执行go程序时,从main开始,main goroutine创建一个新的M,绑定一个P。如果main函数里有其他的goroutine,查询是否有空闲的P,如果有,创建一个新的M,加入新P的本地队列中,绑定其他空闲的P。如果没有空闲的P,那么将G加入全局队列中。每次执行时,循环执行本地队列任务(本地队列和全局队列会交换任务),然后执行全局任务,都没有的话,去其他P里面偷,偷一半。

以银行办理业务为例,客户代表G,窗口代表P,M代表排队通道。sched代表一个全局的排队通道。来了一个客户,将安排到一个空闲的排队通道M里,这个排队通道M绑定一个窗口P(每个排队通道都要绑定一个窗口P,一个窗口P可以有多个排队通道M,N:M)。如果来新客户,看下有没有空闲的窗口P,有的话,开一个新的排队通道M,将新客户安排到这个排队通道里。如果没有空闲的窗口P,此时,每个排队通道M都有客户G,如果排队通道M没有满,那么G安排到一个有空闲位置的M。如果所有的M都满了,那么安排客户G到全局排队通道sched。执行过程中,如果某个客户的任务执行太久,(使用任务计数schedtick判断),将客户安排到排队通道M末尾。(重新排队)。如果某个窗口P对应的排队通道M都空了(一个窗口P可能有多个排队通道M),那么看下全局排队通道有没有客户G,有就过来(M的本地任务和sched全局任务有定期的交换策略),没有的话,去其他窗口P里面偷一半客户G过来执行。

 

https://blog.csdn.net/liangzhiyang/article/details/52669851

https://www.cnblogs.com/lgh344902118/p/11566592.html

https://zhuanlan.zhihu.com/p/27056944

 

posted @ 2021-08-18 17:27  会飞的猿  阅读(109)  评论(0编辑  收藏  举报