GMP Scheduler Code Reading

💡 原文中文,约25800字,阅读约需62分钟。
📝

内容提要

本文分析了GMP调度器的内部实现,包括数据结构和初始化过程。调度循环是核心,通过获取可运行的goroutine来执行。系统调用和线程管理是调度器的一部分。主线程和监控线程分别负责执行和后台任务。

🎯

关键要点

  • GMP调度器的概述包括G、M、P的定义。
  • GMP调度器的内部实现主要在$GOROOT/src/runtime/runtime2.go文件中。
  • G对象表示goroutine,具有更低的内存占用和更快的启动速度。
  • stack对象表示goroutine的执行栈内存范围。
  • sudog对象表示等待队列中的goroutine,主要用于channel的发送/接收。
  • gobuf对象表示goroutine的运行现场,用于保存和恢复上下文。
  • goroutine的状态列表包括_Gidle、_Grunnable、_Grunning等。
  • 调度器最多可以创建10000个线程,活跃线程数由GOMAXPROCS控制。
  • m对象表示线程,和处理器p绑定以执行goroutine逻辑代码。
  • p对象作为线程和goroutine的中间层,负责调度和管理goroutine队列。
  • schedt对象是全局调度器的运行时表示,包含多个重要字段。
  • 调度器初始化通过schedinit方法完成,设置线程数量上限。
  • newproc方法用于创建新的goroutine并将其放入处理器的运行队列。
  • 调度循环通过schedule方法实现,核心是找到可运行的goroutine执行。
  • gopark方法将goroutine状态设置为等待,park_m方法解除M和goroutine的绑定。
  • LockOSThread和UnlockOSThread方法用于绑定和解除goroutine与操作系统线程的关系。
  • 主线程只能在runtime.m0线程上运行,监控线程负责后台任务。
  • checkdead方法用于死锁检测,确保系统正常运行。
  • GMP调度器的设计通过中间层P解决了多个性能问题。
➡️

继续阅读