GO的GMP的理解

GMP的深入理解-go语言学习

`
第一章 GPM的学习和理解



本文说明了GPM的关系,以及调度的过程:

一,GPM各个的意思和作用

G: 表示goroutine,存储了goroutine的执行stack信息、goroutine状态以及goroutine的任务函数等;另外G对象是可以重用的。
P: 表示逻辑processor,P的数量决定了系统内最大可并行的G的数量(前提:系统的物理cpu核数>=P的数量);P的最大作用还是其拥有的各种G对象队列、链表、一些cache和状态。
M: M代表着真正的执行计算资源,物理Processor。在绑定有效的p后,进入schedule循环;而schedule循环的机制大致是从各种队列、p的本地队列中获取G,切换到G的执行栈上并执行G的函数,调用goexit做清理工作并回到m,如此反复。M并不保留G状态,这是G可以跨M调度的基础。

二、GPM之间的配合作用

1)G的出现

新创建一个goroutine(G)时会,检查是否有闲置的p(p的数量是根据cpu中的线程决定的,比如双核四线程,就可以认为是p最大数量可以为4),若有,则将G添加到已经绑定好的P和M中的P的G队列中,等待被调度。

问题1,P和M是如何绑定的
问题2,如果没有了闲置的P,那么G放入到哪个P的队列中

2)G的调度其实是一种抢占式的调度。(饥饿游戏-抢)

当程序启动后,会存在一个sysmon线程(监控线程),属于制定规矩的超级管理者,它会一直存在而且不会受控于GPM规则。当它检查所有的G时,发现某个G运行时间已经很长了(time=10ms),那么sysmon就对该G进行留校察看处分将其标志位置为true,表示该G在下次调用函数时就会被其他的G(已经在队列中等了很久了)抢占,让出对应的M供新的G进行调用

问题1,被抢占的G是否是又被重新放到其所在的队列中

3)GPM之间的关系图

G如果想运行起来必须依赖P,P是它的逻辑处理单元,但是P要想真正的运行,他也需要与M绑定(this狐假虎威),这样才能真正的运行起来,P和M的这种关系就相当于Linux系统中的用户层面的线程和内核的线程是一样的

一般的,处理器P的协程G额外创建的协程会加入本地的queue中,但如果本地队列已满,或者阻塞的协程被唤醒,则协程会被放入全局的queue中。

三.GPM的调度详细分析

这种绑定关系是如何进行调度的呢?
每个处理器P维护着一个协程G的队列,处理器p依次将协程G调度到M中执行。协程G结束后,处理器P会再次调度一个协程G到M执行,P是一个调度者,M是一个执行的车间。
P除了查看自己的G队列,还会周期的查看全局队列。

1.抢占式调度

1)带有函数被抢占的形式

只要一个G有函数调用,都有可能被抢占。原理是:在每个函数或方法的入口,加上一段额外的代码,让runtime有机会检查是否需要执行抢占调度。

故事是这样的:

初来乍到的小G人生地不熟,但小G很幸运就绑到了一个大款P,P也有比较硬的后台M,M提供给P各种运营资源,这样小G也是如鱼得水。

这天G开开心心的准备去外面溜一圈,他正准备去新商场(function)去消费,突然他发现P给的信用卡被锁了,而自己也被放到了一堆和自己类似的人那里,问了才知道,这些人都是P用花言巧语哄骗的过来的P追随者,她们每个人都气哄哄的,只听有的人发着牢骚:我才享受这种无忧无虑的日子10ms,就把我卡锁了,太无情了。

小G心想:没办法,谁让我们离了P没办法生活呢,只能这样默默的忍受着了。

慢慢的前面的人一个个又都开心的离开了,小G心里正纳闷的时候,突然自己又被放回到大商场,信用卡也有了钱,钱又一次占领了小G的精神高地,之前P的无情已经被抛之脑后了。

2)channel阻塞或network I/O情况下的调度

如果G被阻塞在某个channel操作或network I/O操作上时,G会被放置到某个wait队列中,而M会尝试运行下一个runnable的G;如果此时没有runnable的G供m运行,那么m将解绑P,并进入sleep状态。当I/O available或channel操作完成,在wait队列中的G会被唤醒,标记为runnable,放入到某P的队列中,绑定一个M继续执行。

3)syscall阻塞下的调度

如果G0被阻塞在某个system call操作上,那么不光G0会阻塞,执行该G0的M0也会解绑P(实质是被sysmon抢走了),与G0一起进入sleep状态。如果此时有idle的M1,则P与其绑定继续执行其他G;如果没有idle M,但仍然有其他G要去执行,那么就会创建一个新M。

当G0结束系统调用后,根据M0的是否能获取到P,对G0进行不同的处理:
如果有空闲的P,则获取一个P,继续执行G0
如果没有,则将G0放入全局队列,等待被其他P调度。然后M0进入缓存池睡眠

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值