当前位置:网站首页>go GMP模型
go GMP模型
2022-07-20 07:15:00 【go|Python】
go GMP模型
GMP原理解析
操作系统的线程会被操作系统内核调度时会挂起当前执行的线程并将它的寄存器内容保存到内存中,选出下一次要执行的线程并从内存中恢复该线程的寄存器信息,然后恢复执行该线程的现场并开始执行线程。从一个线程切换到另一个线程需要完整的上下文切换。因为可能需要多次内存访问,索引这个切换上下文的操作开销较大,会增加运行的cpu
周期。
区别于操作系统内核调度操作系统线程,goroutine
的调度是Go语言运行时(runtime
)层面的实现,是完全由 Go
语言本身实现的一套调度系统——go scheduler
。它的作用是按照一定的规则将所有的 goroutine
调度到操作系统线程上执行。
在经历数个版本的迭代之后,目前 Go 语言的调度器采用的是 GPM
调度模型。
其中:
- G:表示
goroutine
,每执行一次go f()
就创建一个 G,包含要执行的函数和上下文信息。 - 全局队列(
Global Queue
):存放等待运行的 G。 - P:表示
goroutine
执行所需的资源,最多有GOMAXPROCS
个。 - P 的本地队列:同全局队列类似,存放的也是等待运行的G,存的数量有限,不超过256个。新建 G 时,G 优先加入到 P 的本地队列,如果本地队列满了会批量移动部分 G 到全局队列。
- M:线程想运行任务就得获取 P,从 P 的本地队列获取 G,当 P 的本地队列为空时,M 也会尝试从全局队列或其他 P 的本地队列获取 G。M 运行 G,G 执行之后,M 会从 P 获取下一个 G,不断重复下去。
Goroutine
调度器和操作系统调度器是通过 M 结合起来的,每个 M 都代表了1个内核线程,操作系统调度器负责把内核线程分配到 CPU 的核上执行。
单从线程调度讲,Go语言相比起其他语言的优势在于OS线程是由OS内核来调度的, goroutine
则是由Go运行时(runtime)自己的调度器调度的,完全是在用户态下完成的, 不涉及内核态与用户态之间的频繁切换,包括内存的分配与释放,都是在用户态维护着一块大的内存池, 不直接调用系统的malloc
函数(除非内存池需要改变),成本比调度OS线程低很多。 另一方面充分利用了多核的硬件资源,近似的把若干goroutine
均分在物理线程上, 再加上本身 goroutine
的超轻量级,以上种种特性保证了 goroutine
调度方面的性能。
GOMAXPROCS
Go运行时的调度器使用GOMAXPROCS
参数来确定需要使用多少个 OS 线程来同时执行 Go 代码。默认值是机器上的 CPU 核心数。例如在一个 8 核心的机器上,GOMAXPROCS
默认为 8。Go语言中可以通过runtime.GOMAXPROCS
函数设置当前程序并发时占用的 CPU逻辑核心数。(Go1.5
版本之前,默认使用的是单核心执行。Go1.5
版本之后,默认使用全部的CPU 逻辑核心数。)
func main() {
for i := 0; i < 50; i++ {
go func() {
fmt.Println(i)
}()
}
time.Sleep(1*time.Second)
// go 协程被调度执行,多以打印的i,不确定是多少
}
边栏推荐
- 【二叉树】重建二叉树(先序找根,中序分治)
- C#使用合并的方法判断两个List是否相等,是否包含
- svn 的tag,分支管理,merge合并冲突
- MySQL indexes and transactions
- The projection layer released by leaflet loading hypergraph reports an error uncaught no projection definition for code XXXX
- 国内的边缘计算组织和产品调研
- Top ten best automated test tools in the world in 2022
- 每日三题 7.16
- 力扣 745. 前缀和后缀搜索
- Kubernetes deploys single node redis service
猜你喜欢
03 beautifulsoup parsing library
The difference between copy and copy in XMIND
2022.07.19 (lc_; sword finger offer II 041. Average value of sliding window)
MySQL JDBC编程
MySQL索引与事务
Docker 学习笔记(十二)-- 部署Redis集群 实战
Jmeter 接口必加元素
MySQL的增删查改【进阶】
Autojs learning - realize transparent status bar
01 Course Introduction & Reptile overview
随机推荐
[learning notes] arc144
Fluent print widget level list
解决你的绩效管理问题的3种方法
MySQL表的增删改查(初阶)
MySQL JDBC programming
vulntarget漏洞靶场-vulntarget-b
Error: Cannot run with sound null safety, because the following dependencies don‘t support null safe
2022.07.19 (lc_; sword finger offer II 041. Average value of sliding window)
Error: Cannot run with sound null safety, because the following dependencies don‘t support null safe
Force buckle 745 Prefix and suffix search
MySQL索引与事务
DeFi 2.0的LaaS协议,重振DeFi赛道发展的关键
那些做3D、数字人、元宇宙的年轻人,究竟有多赚钱?
One question per day · 731 My schedule | · array
Fundamentals of number theory-
英飞凌 AURIX TC3XX 系列单片机的链接文件
年中总结及个人有感
每日一题:链表内指定区间反转
IP command usage guide
pango debug抓信号