GMP模型详解


一、CSP并发模型

1、CSP是什么?

CSP是Go的一种并发模型,是通过Goroutine和channel实现的,用于描述两个独立的并发实体(Goroutine)通过共享的通讯 channel(管道)进行通信的并发模型。

2、核心思想

以通信的方式来共享内存,不要以共享内存的方式来通信
CSP的核心观念是将两个并发执行的实体通过通道channel连接起来,所有的消息都通过channel传输。

二、GMP

1、GMP的前身GM

G:G就是我们通过go关键字开启的Goroutine
M:M是内核线程
除了G和M,还会存在一个全局的队列,这个全局队列可以存放多个处于可运行状态的G,M如果想要获取G就需要访问全局队列。
在这里插入图片描述

2、GM的问题

从表面来看,貌似GM就已经挺好的了,那么为什么会出现GMP呢?

①存在单一全局锁
内核线程可以同时存在多个,为了线程安全,全局队列会有一个锁,每次访问都需要先获取这个锁,锁竞争严重。
②频繁的线程阻塞和解阻塞
在存在 syscalls 的情况下,线程经常被阻塞和解阻塞。这增加了很多额外的性能开销。
③Goroutine的传递
G交接下一个G,线程之间会经常交接可运行的Groutine,会导致延迟增加和额外的开销。

3、GMP

G和M我们前面已经提到了,那么P是什么呢?
P:处理器,负责G与M的连接,它能提供线程所需要的上下文环境,也能分配G到它应该去的线程上执行
在这里插入图片描述
P的加入带来了一个本地队列,和全局队列类似,也是用于存放G的,想要获取等待运行的G,需要优先从本地队列获取,访问本地队列无需加锁。虽然我们有了本地队列,但是全局队列仍然是存在的

GM模型里M想要运行G,直接去全局队列里拿就行了;GMP模型里,M想要运行G,就得先获取P,然后从 P 的本地队列获取 G。
在这里插入图片描述
新建 G 时,新G会优先加入到 P 的本地队列;如果本地队列满了,则会把本地队列中一半的 G 移动到全局队列

P的本地队列为空时,就从全局队列里去取。如果全局队列也为空,则会发生work-stealing,M会从其他P的本地队列中偷取G
在这里插入图片描述
如果G发生阻塞,那么M会寻找其他G来执行

如果G发生系统调用,那么M也会进入系统调用状态,而P就会寻找其他空闲的M

4、GMP的数量限制?

G:没有数量限制,理论上和内存有关,创建一个Goroutine需要2~4K的连续内存
M:默认限制数量是10000,可调整
P:受本机核数影响,可调整


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小阿GO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值