当 Go Scheduler 创建新的 M 和 P
Go 运行时中,goroutines、操作系统线程(OS thread)和上下文/处理器(M 和 P)协作管理并发。了解何时创建新的 M 和 P 实体对于高效性能至关重要。
M 和 P 创建
-
M(机器): M 代表操作系统线程,在调度 goroutine 运行时创建。 M的数量最初由runtime.GOMAXPROCS环境变量设置。
-
P(处理器): A P是执行goroutine的处理器。每个 P 都与一个 M 相关联。当 M 阻塞时,可能会创建一个新的 M 来在该 P 上执行 goroutine。
场景分析
In在您的代码示例中,您创建了多个执行阻塞操作的 goroutine。在这种情况下:
- 第一批 goroutine 将被调度在现有的 P 实例上。
- 如果所有 P 的本地队列已满,将创建新的 M 来处理溢出
- 但是,由于您的 goroutine 在 go func() 内执行阻塞操作,因此与阻塞的 goroutine 关联的 M 将从 P 中移除,并放入空闲线程池中。
- 新将创建 M 来替换被阻塞的 M 并继续在该 P 上执行 goroutine。
结论
总而言之,Go 调度程序会在以下情况下创建一个新的 M: goroutine 已计划运行,但空闲的操作系统线程不可用。当现有 P 的本地队列已满时,将创建新的 P。然而,在阻塞 goroutine 的情况下,创建的 M 数量可能会超过虚拟核心的数量,因为每个阻塞操作都需要一个单独的 M。
其他资源
- [Go 博客中的 GOMAXPROCS](https://blog.golang.org/GOMAXPROCS)
- [Go Goroutine、操作系统线程和 CPU 管理](https://godoc.org/ runtime/debug#SetMaxThreads)
- [GMP 基础知识](https://www.programmersought.com/article/79557885527/)
以上是Go调度器什么时候创建新的M和P?的详细内容。更多信息请关注PHP中文网其他相关文章!