1、P的数量:
由启动时环境变量$GOMAXPROCS或者是由runtime的方法GOMAXPROCS()决定(默认是1)。这意味着在程序执行的任意时刻都只有$GOMAXPROCS个goroutine在同时运行。2、M的数量:
go语言本身的限制:go程序启动时,会设置M的最大数量,默认10000.但是内核很难支持这么多的线程数,所以这个限制可以忽略。runtime/debug中的SetMaxThreads函数,设置M的最大数量一个M阻塞了,会创建新的M。M与P的数量没有绝对关系,一个M阻塞,P就会去创建或者切换另一个M,所以,即使P的默认数量是1,也有可能会创建很多个M出来。
3、P何时创建:在确定了P的最大数量n后,运行时系统会根据这个数量创建n个P。
4、M何时创建:没有足够的M来关联P并运行其中的可运行的G。比如所有的M此时都阻塞住了,而P中还有很多就绪任务,就会去寻找空闲的M,而没有空闲的,就会去创建新的M。
M选择哪一个P关联?M会选择导致此M被创建的那个P关联。什么时候会切换P与M的关联关系?当M因系统调用而阻塞时(M上运行的G进入了系统调用的时候),M与P会分开,如果此时P的就绪队列中还有任务,P就会去关联一个空闲的M,或者创建一个M进行关联。(也就是说go不是像libtask一样处理IO阻塞的?不确定。)
就绪的G如何选择进入哪个P的就绪队列?默认情况下:因为P的默认数量是1(M不一定是1),所以如果蜜桃成人网站入口不改变GOMAXPROCS,无论蜜桃成人网站入口在程序中用go语句创建多少个goroutine,它们都只会被塞入同一个P的就绪队列中。有多个P的情况下:如果修改了GOMAXPROCS或者调用了runtime.GOMAXPROCS,运行时系统会把所有的G均匀的分布在各个P的就绪队列中。如何保证每个P的就绪队列中都会有G如果一个P的就绪队列所有任务都执行完了,那么P会尝试从其他P的就绪队列中取出一部分到自己的就绪队列中,以保证每个P的就绪队列都有任务可以执行。