零声golang云生原Go语言 分布式 微服务 DevOps k8s二次开发
2023-06-10 11:01 作者:一起学习fee1024 | 我要投稿
golang 的 GPM 模型
为了实现 golang 的调度,golang 抽象出了三个结构,也就是我们常见的 G、P、M。
G:也就是协程 goroutine,由 Go runtime 管理。我们可以认为它是用户级别的线程。
goroutine 非常的轻量,初始分配只有 2KB,当栈空间不够用时,会自动扩容。同时,自身存储了执行 stack 信息、goroutine 状态以及 goroutine 的任务函数等。
P:processor 处理器。P 的数量默认跟 CPU 的核心数一样,如果是多核的 CPU,则会有多个 P 会被创建。
每当有 goroutine 要创建时,会被添加到 P 上的 goroutine 本地队列上,如果 P 的本地队列已满,则会维护到全局队列里。
在进行调度时,会优先从本地队列获取 goroutine 来执行。
如果本地队列没有,会从其他的 P 上偷取 goroutine。
如果其他 P 上也没有,则会从全局队列上获取 goroutine。
这样通过上面的策略,就能尽最大努力保证有 goroutine 可运行。
M:系统线程。在 M 上有调度函数,它是真正的调度执行者,M 需要跟 P 绑定,并且会让 P 按上面的原则挑出个 goroutine 来执行。
M 虽然从 P 上挑选了 G 执行,但 M 并不保存 G 的上下文信息,而是 G 自
己保存了相关信息,这样有利于转移到其他 M 上,在不同的 M 上运行。
