
Golang的GMP内存模型(一)
缺点:单一执行流程、计算机只能一个一个业务处理
解决了阻塞问题,CPU轮询,进程切换需要保存状态,造成了巨大的时间浪费
面临的问题是 线程越多,不停的切换轮询CPU,代价越大。所以在语言层面,让多个协程(任务绑定在一个线程内完成,可以减少线程切换)
发布日期:2021-05-06 23:58:28
浏览次数:26
分类:精选文章
本文共 1111 字,大约阅读时间需要 3 分钟。
1.调度器的由来

进程阻塞所带来的CPU浪费时间
2.多进程/多线程操作系统



M:N 模型化解了问题,如果一个协程阻塞,可以绑定到下一个线程

2.GMP模型的设计思想
在调度器中,出列M(thread)和G(goroutine),又引进了P(Processor)。
1.GMP模型
在Go中,线程是运行goroutine的实体,调度器的功能是把可运行的goroutine分配到工作线程上。

- 全局队列(Global Queue):存放等待运行的G。
- P的本地队列:同全局队列类似,存放的也是等待运行的G,存的数量有限,不超过256个。新建G’时,G’优先加入到P的本地队列,如果队列满了,则会把本地队列中一半的G移动到全局队列。
- P列表:所有的P都在程序启动时创建,并保存在数组中,最多有
GOMAXPROCS
(可配置) - M:线程想运行任务就得获取P,从P的本地队列获取G,P队列为空时,M也会尝试从全局队列拿一批G放到P的本地队列,或从其他P的本地队列偷一半放到自己P的本地队列。M运行G,G执行之后,M会从P获取下一个G,不断重复下去。
2.P和M的数量问题
1、P的数量:
-
由启动时环境变量
2、M的数量:$GOMAXPROCS
或者是由runtime
的方法GOMAXPROCS()
决定。这意味着在程序执行的任意时刻都只有$GOMAXPROCS
个goroutine在同时运行。 -
go语言本身的限制:go程序启动时,会设置M的最大数量,默认10000.但是内核很难支持这么多的线程数,所以这个限制可以忽略。
-
一个M阻塞了,会创建新的M。
M与P的数量没有绝对关系,一个M阻塞,P就会去创建或者切换另一个M,所以,即使P的默认数量是1,也有可能会创建很多个M出来。
3.P和M何时会被创建
1、P何时创建:在确定了P的最大数量n后,运行时系统会根据这个数量创建n个P。
2、M何时创建:没有足够的M来关联P并运行其中的可运行的G。比如所有的M此时都阻塞住了,而P中还有很多就绪任务,就会去寻找空闲的M,而没有空闲的,就会去创建新的M。
发表评论
最新留言
很好
[***.229.124.182]2025年04月04日 04时58分58秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
PHP 脚本不报错
2019-03-06
代码整洁之道小结
2019-03-06
悲观锁与乐观锁
2019-03-06
js new Date 创建时间默认是8点
2019-03-06
Python实现cmd命令连续执行
2019-03-06
罗马数字
2019-03-06
IO多路复用小故事
2019-03-06
纠错码简介
2019-03-06
码云 Pages 搭建
2019-03-06
《论可计算数及其在判定上的应用》简单理解
2019-03-06
中国剩余定理证明过程
2019-03-06
kafka告警简单方案
2019-03-06
java接口的应用举例
2019-03-06
java接口中多继承的问题
2019-03-06
java中Object.equals()简单用法
2019-03-06
一个小例子对多态简单的理解
2019-03-06
poj 2187 Beauty Contest(凸包求解多节点的之间的最大距离)
2019-03-06
poj 2492A Bug's Life(并查集)
2019-03-06
ZZUOJ 1199 大小关系(拓扑排序,两种方法_判断入度和dfs回路判断)
2019-03-06