MPG 模式的介绍 | 学习笔记

简介: 快速学习 MPG 模式的介绍

开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程MPG 模式的介绍】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/626/detail/9749


MPG 模式的介绍

 

内容介绍

一,MGP 模式基本介绍

二,MPG 模式运行的状态1

三,MPG 模式运行的状态2

 

一,MGP 模式基本介绍

Go 的调度器内部有三个重要的结构: M,P,S
M:代表真正的内核 0S 线程,和 POSIX 里的 thread 类似,真正起作用的
G:代表一个 goroutine,有自己的栈,instruction pointer 和其他信息(正在等待的 channel 等等),用于调度。
P:代表调度的上下文,可以把它看做一个局部的调度器,使 go 代码在一一个线程上跑,是实现从 N:1到 N:M 映射的关键。

image.png


第一个结论,看一下主线程,它是一个物理线程,主线程是直接作用在一个 cpu 上面的是重量级的非常的耗费 cpu 资源组建,一个物理级的操作系统来控制的携程,是从主线程开启的是轻量级的线程是相对来说资源消耗相对较小形成机制重要的一个特点可以轻松的开启三个携程其他编程,语言的并发机制一般是基于线程那开启过的线程资源耗费大。这个快速入门的一个小节先把它反射到里面后接着快速度它关掉。

快速入门重点就是做了三个的缩影。接着,来检验一下 gro ton,的一个调度模型是什么机制。这个 MPG 一般就是面试。第一个代表是操作系统的一个主线测。M 是一种相当于是一个物理极限,所以它比较费资源。P 可以认为是一个在整个执行过程中的一个上下文环境,上下文环境是在很多编程语言里面都会有提到东西,上下文环境,可以简单的说运行的时候需要一些资源或者他的一个当时的操作系统的状态。就好像这儿有一个 M 主线程。在我们运行过程中,比如说在一个位置,需要开启一个携程,那么在携程起来的时候需要有一个商业的环境。就好像一个人一样,这个人是在什么地方生活得有空气,有水。一个一个连起来时候,它要依赖于当前操作系统还有这个内存的分配,以及还有没有可分配,这些都可以成为一个很重要的概念,就是他需要的资源和它运行。

创建这个过程中,比如说在这个专业的运行过程,突然在这个这个地方,需要去开启一个携程,那么这个携程网还可以形成一个规定它可以形成一个对比,比如又需要开发一个中间一个鞋城,这又算是一个节点,或者是图文的一个环境,那么从这又可以继续开启另外的其他的携程,同样也可以形成一个,形成一个对立,形成对立相对简单。

 

二,MPG 模式运行的状态1

image.png

当前程序有三个 M,如果三个 M 都在一一个 cpu 运行, 就是并发,如果在不同的 cpu 运行就是并行。
M1,M2,M3正在执行一个 G, M1的协程队列有三个,M2 的协程队列有3个,M3 协程队列有2个。
从上图可以看到: Go 的协程是轻量级的线程,是逻辑态的,Go 可以容易的起上万个协程。
其它程序 c/java 的多线程, 往往是内核态的,比较重量级,几千个线程可能耗光 cpu。

要理解这个事首先得了解操作系统是怎么运用线程的。一个线程就是一个栈加一堆资源。操作系统一会让 cpu 跑线程 A,一会让 cpu 跑线程 B,靠 A  B 的栈来保存 A  B 的执行状态。每个线程都有自己的栈。
但是线程又贵,所以 go 发明了 goroutine. 大致就是说给每个 goroutine 个分配在 heap 里面的栈来模拟线程栈。比有3个 goroutine, A,B,C, 就在 heap 开发出三个栈。然后 Go 让一个单线程的 scheduler 开始这三个栈。相当于{ A(); B(); C() },连续的,串行的跑。和操作系统不太一样的是,操作系统可以随时随地把线程停掉,切换到另一个线程。这个单线程的 scheduler 那个能力,就是 user space  的一段朴素的代码,他跑 A 的时候控制权是在 A 的代码里面。A 自己不退出也没有其他办法。所以 A 跑一小段后需要主动主动反馈进行休息, 这时候可以看做A返回了。A 返回了 B 就可以跑了,然后 B 小段保存状态,返回,然后 C 再跑。C 跑一段返回。
样跑完 A(); B(); C()}之后, 我们发现,好像他们都只跑了小段。所以外面要包一个循环,大致是:
goroutine_ list = [A, B, Cwhile (goroutine) :for goroutine in goroutine_ list:r = goroutine()if r. finished():goroutine_ list. remove(r)

当前程序有三个 M,三个 M 有三个 em,如果三个都运行在一个 cpu,就称之为并发。

概念第二点 M1M2M3正在执行一个。可以知道 M1现在正在执行一个 G。携程正在实行,同样M来执行一个 G,也在同时执行。

在 P 的地方,它可以开启 G,这种多的情况下,可以进行一个队列,这是它的一个模式。每个携程可以去完成的一个任务。那么其他程序比如说 C,是多线程,线程往往是内核态的比较重量级,几千个线程就可能耗光 cpu,耗费 cpu 这是他的第一种状态

 

三,MPG 模式运行的状态2

分成两个部分来看。
原来的情况是 MO 主线程正在执行 G0 协程,另外有三个协程在队列等待。
如果 G0 协程阻塞,比如读取文件或者数据库等。
这时就会创建 M1主线程(也可能是从已有的线程池中取出 M1),并且将等待的3个协程挂到 M1下开始执行,M0 的主线程 下的 GO 仍然执行文件 io 的读写。
这样的 MPG 调度模式,可以既让 G0 执行,同时也不会让队列的其它协程一直阻塞, 仍然可以并发/并行执行。
等到 G0 不阻塞了,M0 会被放到空闲的主线程继续执行(从已有的线程池中取),同时 G0 又会被唤醒。

image.png

举一个动态的 MPG 运行的一个状态二。

比如现在情况,分成两部分来看是 M0 M0,这就是主线程正在执行,等待如果遇到了一个 go 携程被阻塞什么情况下会堵塞这个一个携程,例如文件或者数据库,因为文件时不知道要花多少时间,操作系统它就是这个携程,底层就会等待一个文件到底要多久不知道,对计算机来说已经很长了,认为在读文章的时候,cpu 有点浪费时间等,所以此时可能会做这样的事情 cpu 他们一个空闲状态就会创建一个叫 M1的,一个主题,也有可能这个事情已经从有了一个现场秩序,只有根据当时的情况,M0再运行或者有可能维护一个线程池。 

例如里面有可能预留一个,或者一可能没有,这个就跟操作系统底层相关联,如果有,就把这个 M 一个拿过来并进行唤醒,让它工作,如果没有,就出现这样的情况,跟操作系统底层有关系,跟上下文环境有关系。M 用就是原来进行等待现在立即就来工作。并且将等待的三个携程挂到 M1下面去执行。其实本质上来说可能就是一个列表,也可能是一个队列的数据结构,完全可以做挂到,可以简单的认为让这个 M1指向。对于一个队列,我们可以把这个地址给他,就相当于挂到上面后就开始执行,那么 F0这个主线程,叫做功能仍然执行这个,他原来的读写,例如 MPG 模式既可以正常的读文件,文件同时也不会让队列中的其他一直堵塞。此时这个东西,就有效的把 cpu 运行起来了,其他这样的情况,可以既保证主线程的一种进程,又能够保证形成一种并发和并行都能持续的状态

比如跑完一圈 A, B, C 之后任何一个都没执行完,那么就在回到 A 执行一次。由于把 A 的栈保存在了 HEAP 里,此时就可以把A的栈复制粘贴会系统栈里(其实真实情况不是这样的,会意即可),然后再调用 A,这时候由于 A 是跑到一半自己说跳出来的,所以会从刚刚跳出来的地方继续执行。

image.png

图中看,有2个物理线程 M,每一个 M 都拥有一个 context(P),每一个也都有一个正在运行的 goroutine。
P 的数量可以通过 GOMAXPROCS()来设置,其实也就代表了真正的并发度,即有多少个 goroutine 可以同时运行。
图中灰色的那些 goroutine 并没有运行,而是出于 ready 的就绪态,正在等待被调度。P维护着这个队列(称之为 runqueue)
Go 语言里,启动一个 goroutine 很容易: go function  就行,所以每有一个 go 语句被执行,runqueue  队列就在其末尾加入一个
goroutine,在下一个调度点,就从 runqueue 中取出(如何决定取哪个 goroutine ? )一个 goroutine 执行。
为何要维护多个上下文 P?因为当一个 0s 线程被阻塞时,P 可以转而投奔另一个 OS 线程!
图中看到,当一个 0S 线程 MO 陷入阻塞时,P 转而在 os 线程M1I上运行。调度器保证有足够的线程来运行所以的 context P。

相关文章
|
3月前
|
编解码 语音技术 内存技术
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
《FFmpeg开发实战:从零基础到短视频上线》一书中的“5.1.2 把音频流保存为PCM文件”章节介绍了将媒体文件中的音频流转换为原始PCM音频的方法。示例代码直接保存解码后的PCM数据,保留了原始音频的采样频率、声道数量和采样位数。但在实际应用中,有时需要特定规格的PCM音频。例如,某些语音识别引擎仅接受16位PCM数据,而标准MP3音频通常采用32位采样,因此需将32位MP3音频转换为16位PCM音频。
119 0
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
|
3月前
|
编解码 关系型数据库 计算机视觉
Opencv学习笔记(十一):opencv通过mp4保存为H.264视频
本文介绍了如何在OpenCV中通过使用cisco开源的openh264库来解决不支持H.264编码的问题,并提供了完整的代码示例。
270 0
Opencv学习笔记(十一):opencv通过mp4保存为H.264视频
|
3月前
|
Android开发 开发者
FFmpeg开发笔记(五十七)使用Media3的Transformer加工视频文件
谷歌推出的Transformer,作为Jetpack Media3架构的一部分,助力开发者实现音视频格式转换与编辑。Media3简化了媒体处理流程,提升了定制性和可靠性。Transformer可用于剪辑、添加滤镜等操作,其示例代码可在指定GitHub仓库中找到。要使用Transformer,需在`build.gradle`中添加相关依赖,并按文档编写处理逻辑,最终完成音视频转换任务。具体步骤包括配置剪辑参数、设置空间效果以及监听转换事件等。
72 0
FFmpeg开发笔记(五十七)使用Media3的Transformer加工视频文件
|
8月前
|
缓存 编解码
FFmpeg开发笔记(十四)FFmpeg音频重采样的缓存
FFmpeg在视频流重编码和音频重采样中使用缓存机制。在音频文件格式转换时,特别是对于帧长度不固定的格式如ogg、amr、wma,需处理重采样缓存。通过调用`swr_convert`,传入空输入和0大小来清空缓存。在`swrmp3.c`中,修改帧样本数处理,并在循环结束后添加代码以冲刷缓存。编译并运行程序,将ogg文件重采样为MP3,日志显示操作成功,播放转换后的文件确认功能正常。
166 7
FFmpeg开发笔记(十四)FFmpeg音频重采样的缓存
|
Python
tinytag-用于读取MP3,OGG,FLAC和Wave文件的音乐元数据的python库
tinytag是一个python库,用于使用python读取MP3,OGG,OPUS,MP4,M4A,FLAC,WMA和Wave文件的音乐元数据。特征: - 读取音频文件的标签,长度和封面图像 - 支持的格式:(MP3 (ID3 v1, v1.1, v2.2, v2.3+)、Wave/RIFF、OGG、OPUS、FLAC、WMA、MP4/M4A/M4B) - 纯python,无依赖 - 支持python 2.7和3.4或更高版本 - 高测试覆盖率 - 仅几百行代码(只需将其包含在您的项目中即可!)
1983 0
tinytag-用于读取MP3,OGG,FLAC和Wave文件的音乐元数据的python库
C4D点模式下无法使用mp缝合工具
C4D点模式下无法使用mp缝合工具
123 0
C4D点模式下无法使用mp缝合工具
|
存储 编解码 缓存
Hi3516开发笔记(十):Qt从VPSS中获取通道图像数据存储为jpg文件
上一篇已经将himpp套入qt的基础上进行开发。那么qt中拿到frame则是很关键的交互,这是qt与海思可能编解码交叉开发的关键步骤。
Hi3516开发笔记(十):Qt从VPSS中获取通道图像数据存储为jpg文件
|
编解码 计算机视觉 Windows
Qt实用技巧:使用QMediaPlayer和Windows自带组件播放swf、rmvb、mpg、mp4等视频文件
Qt实用技巧:使用QMediaPlayer和Windows自带组件播放swf、rmvb、mpg、mp4等视频文件
Qt实用技巧:使用QMediaPlayer和Windows自带组件播放swf、rmvb、mpg、mp4等视频文件
|
编解码 索引 视频直播
第一个将Palette Mode引入VVC(H.266),阿里云在JVET会议上引起关注
本文作者阿里云视频云高级技术专家睿柯如是说:阿里云在屏幕视频编码技术和应用上有世界领先的团队。6月中国AVS会议中,阿里云提出提案分析屏幕视频编码的应用需求,引起AVS组织关注,采纳阿里云的提案成为下一代AVS3的需求。
5028 0
第一个将Palette Mode引入VVC(H.266),阿里云在JVET会议上引起关注
|
测试技术 容器
2-AVI--Fragment生命周期测试
零、前言 [1].两个Fragment,点击左右按钮切换相应的Fragment [2].观察Activity 和两个Fragment生命周期变化 [3].
1123 0