GO的调度

我是我以为我懂了先生,以为自己知道go是怎样调度的,其实深入想一下,自己不了解的太多了。就拿最广而告之的M P G来说吧。

M:拥有PCB结构,在内核中有一席之地的内核级线程。

tip:go之父设计网络IO调用时候,tcp连接参数全部都是non-block模式,注意不理解这个,有可能会线程暴涨哦~~~~非阻塞,从调用者的角度,不会阻塞自身一直等下去,倘若每一个ioRead阻塞一个M,多个netIO的话,M还不得暴涨上天。设置了non-block模式,如果线程io的时候阻塞,那么这个线程就可以被释放出来,继续执行其他的go程,从而充分利用cpu,并且不必切换线程就可以更换执行体go

P:go语言之父帮我们实现的数据结构,处于用户态的进程空间,被G们崇拜,G对P的认识,如果类比到传统开发上,PCB对CPU的认识吧,至高无上的老大地位,离开P,G将饿死,永远得不到执行。p的数量,可以在系统环境变量GOMAXPROCS看到,或者自己设置runtime.GOMAXPROCS()。P的数量固定意味着任意时刻只有固定数量的线程在运行G。

G:P的小弟,是程序员创建的一个个用户态下面的最小执行体。

G以为是在P上跑的,其实只有P自己知道,他真正依赖的是M。而M要想运行一个G,也离不开P.P可以说是M的上下文环境吧。

好了情景分析:现在有一个M,他叫M0,他正在运行一个G,名字我们叫他G0,这个G0去系统调用了,完了,M0陷入了内核态,阻塞了,怎么办,P难道也陪着M等着吗,不会的,go之父也想到了这种情况,宝贵的P是有限的,不能就这样干等,好吧,go之父实现go的时候,对这个情景的处理是,哼,我再创建一个M(也可能是从线程池拿一个M,看完后面就理解了),我姑且叫他M1吧,你M0不是阻塞了吗,把P丢出来,让p为M1服务,继续执行G对列中的G.

过一会,无法肉脑感知的时间片段过后,M0回来了,呜呜,我的P,没有P我怎么运行G0啊,去偷一个P,偷到就万事大吉,偷不到,就把这个G0放到一个全局的runqueue中,P都会周期性检查这个对列的孤儿G去执行。而M0就会去线程池乖乖呆着,或者进入休眠,嗯,休眠回头再探。

P是个勤劳的孩子,当他消耗完了自己本地的Go对列之后,还会去全局GO对列拉任务,还会偷任务,好吧,go之父就是这么调皮,唯恐P浪费掉了,收拾他干活。

嗯,如果你问我为啥要个P啊,就像买房子,我就不想通过中介,虽然此处P并不是proxy这个词,就想让M和G随机结对,额,虽然我也觉得目前自己懂得不深入,但是我觉得,M和G多对多,你不拉一个P,怎样去充分利用M啊,我觉得这是生产者消费者管理的哲学,全都是M-G,那和传统的多线程有啥区别啊。多了一些执行体的区别?我只想问你,离开P,你用什么来高效管理M和G们结识。总之,可以理论上无限多的M们,和理论上可以无限多的G们,请来一个有限数量的P吧,来更好理清这些乱麻。好让我不切M的情况下,能够运行多个G.M不知道他在一个cpu的时间片段运行了多个G,只有我知道。哼~自作聪明

好了,理解的还是不深入以后再补充,至少不做我以为我知道先生

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值