Go的GMP调度器

Go的GMP调度器

上一篇文章关联链接地址点击

前言:

最后有讲系统级别多线程、多进程的问题.

最大的问题其实就是资源浪费,切换成本高

所以导致很多语言对线程的控制要求比较高,否则容易出现内存溢出,或者频繁的让cpu滴使用
率达过高

Go的GMP就很好的解决了这部分的问题。这也是Go逐渐成为热门语言的原因之一。

线程补充:

线程是系统级别进行控制(系统态)。

线程会由机器的多核数量来达到是否存在并行的情况。

协程 co-routine

是有用户态进行管理操作

CPU

cpu只看系统态,只会看向线程,从而在线程和协程中,还有着调度器进行分配管理。

通俗一点的说法就是:通过调度器把不同的协程放入线程执行.(不理解的这么想也是可以的)

那么如何匹对呢?

线程和协程的对应关系

假设 

	情况一:一个线程通过调度器对应多个的协程,那么在普通情况下确实会加快效率,节省cpu调度,但是
	如果协程发生阻塞,那该线程也会陷入等待,后面的协程也将会陷入等待。
	
	情况二: 一对一,一个线程对应一个协程,那这种情况就和普通的多线程系统无异,差不多就是全交予
	系统进行处理。
	
	情况三:多对多,多个线程对应多个协程,按照这样的思路,确实可以进行有效的切换,重点在于调
	度器是如何分配线程和协程的了。

GMP

G : goroutine 协程

M : thread 线程
    M列表:当前操作系统分配到Go程序的内核线程数
  (限制最大量是10000 可忽略 根本不会开着这么多 当然也可通过代码进行调整)
    当M发生阻塞时,则会创建新的M。
    当M空闲时,那么就会回收或者睡眠。
    所以M的数量是动态的。
    
P:处理器
	和P有关的特征:
	p每个处理器的个数会对应着有本地队列,来存放G
	本地队列大小  不超过 256G
	全局队列:存放等待运行的G
	一般都是优先会把写成存放在P的本地队列中,满了之后就会存放在全局队列。
	程序启动时创建
	最多有GOMAXPROCS个(可配置)(简称核数)

使用用户态来控制协程为何就会效率高一些.

1.复用线程(避免了多数的无效切换)

2.机制保证了利用率
	偷拿:假设一个P1队列里包含了多个G协程,那么如果P2是空闲状态,则会把P1队列里的G
    偷偷拿到自己的本地队列的执行。
	分离:如果P1队列里存在G1、G2、G3,但是在执行G1时发生了阻塞,让其他G陷入了等待,
    这个时候就会重新创建或者唤醒一个M,把整个P里的队列分离出去,分到新的M上进行
    执行,使CPU绑定新的M,而G1的M则不会被CPU绑定,停止运行,最后再来决定是否
    还需要运行,如果不需要,那么之前的M,则可以直接销毁或者睡眠,如果还需要工作运
    行,则会把G1重新安排到其他队列当中等待运行。
   
3.抢占策略
	以前:co-routine协程当占用cpu进行执行时,如果没有发生阻塞,则会一直执行下去,直到
	执行完毕主动释放才能轮到第二个协程执行。
	go-toutine协程:每个协程执行的时间为10ms,随后再有其他协程执行,这样就是一个平均
	执行的概念,没有优先级概念。

创建协程存入队列的顺序

优先级:
	1.本地队列:也就是执行代码逻辑的该线程M,那么本协程就会存入对应的P本地队列当中
	
	2.全局队列:当本地队列存储已满时,则会进入到全局队列,
	   这边会有误区:
	   
		   误区1:是不是只有当一个p的本地队列满了之后才会存入全局队列这一种
		   情况,当然不是,之前讲的分离,在阻塞时,当创建完M执行一系列过程后,如果该
		   协程阻塞完还是会需要执行,则会直接分配到全局队列当中,等待被执行。
		   
		   误区2:当本地队列存储已满时,比如已经存在了四个G1、G2、G3,G4,最后加入的是G5,
		   是不是只有G5才会被加入到全局队列中去,当然不是,这边会把G1、G2顺序打乱,也加入
		   到全局队列当中,规则就是把当前本地队列中的G对半分,前面一半的G打乱顺序存放到
		   全局队列当中,并且附加上G5.
	   
	3.偷拿,被cpu绑定的M空闲时,会优先获取全局队列中的G,如果全局队列中也没有G,
	   则会在其他P本地队列当中获取G.

--end结束-- 所有的具体调度都会通过一个G0的协程来,G0只做协程调度,也就是程序最开始创建的协程. G0存放着上下文切换的环境,等。 当M执行完一个协程时,则会调用G0来分配下一个协程的调用,而调用下一个协程的逻辑就是上面讲的优先级顺序了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值