Go相关知识储备(一)

1.Go 调度模型 GPM

首先需要明白概念 :

G是goroutine的缩写,保存goroutine的一些状态信息以及CPU的一些寄存器的值,相当于操作系统中的进程控制块。

M是machine的缩写,是一个线程。所有的M有线程栈,每一个M对应着一条操作系统的物理线程,承载G的队列。

P是processer的缩写,在这里是一个抽象概念,不是真正的物理CPU。P为M的执行提供了“上下文”,保存M执行G时的一些资源。

G P M 三者互相依赖,goroutine需要在processor上才能运行,processor为machine提供资源,processor持有待运行的G。

并发:在系统中,某一个时间段有几个程序都处于已启动到结束之间,但是这几个程序在同一个处理机上进行,是会互相抢占资源的。(拓展:工作负载。CPU-Bound/IO-Bound)

并行:在某一个时间点多个程序同时进行,一个CPU在执行一个进程时,另一个CPU可以执行另一个进程,两个进程在同一时间点同时发生,不会互相抢占资源,可以同时进行。

其次,部分详细内容:

M (包含goroutine的线程)工作过程:

第一步,从工作线程本地运行队列中寻找goroutine;

第二步,从全局运行队列中寻找goroutine。为了保证公平调度,M 需要每经过61次调度就需要优先尝试从全局运行队列中找出一个goroutine来运行。又因为全局运行队列是所有工作线程能够访问的,所以在访问它之前需要加上锁

第三步,从其它工作线程的运行队列中偷取goroutine。如果上一步没有找到需要运行的goroutine,则需要调用findrunable从其它工作线程的队列中偷取,在进行偷取前,他会再次尝试从全局运行队列和当前运行队列中查找需要运行的goroutine。

其它知识:

栈:栈分为 普通栈 和 线程栈

普通栈:是指 调度的goroutine组成的函数栈,是可增长的

线程栈:是指 由需要将goroutine放置上的 M 组成的,实质上 M 由goroutine生成,此栈大小固定

队列:队列分为 全局队列 和 本地队列

全局队列:

1.队列中的 G 被所有 M 全局共享, 为了保证数据竞争的问题,需要加锁

2.M 自旋状态下会偷取其它队列的一半G,放置在自身的本地队列上,后续也是先从该队列偷取,没有则从其它本地队列偷取

本地队列:

该队列存储数据资源相同的任务,每个本地队列都会绑定一个 M,指定其完成任务,没有数据竞争,无需加锁处理,处理速度远高于全局队列

线程清理:由于每个 P 都需要绑定一个 M 进行任务执行,所以当清理线程的时候,只需要将 P 释放,M 就失去了任务。主要也分两种情况:

主动释放:例子:当执行 G 任务时有系统调用,当发生系统调用的时候 M 会处于阻塞状态。那么调度器会设置一个超时时间,当超过这个时间,会立刻将 P 释放

被动释放:如果发生了系统调用,有一个专门监控程序,扫描当处于阻塞的 P/M,当系统超过了该时间,会自动将 P 资源抢走。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值