相关信息
今天学习的内容是goroutine的调度
(1) runtime创建最初的线程M0和Goroutine G0,并把二者关联。
(2)调度器初始化:初始化M0、栈、垃圾回收,以及创建和初始化由GOMAXPROCS个P构成的P列表,如图所示
(3)示例代码中的main( )函数是main.main,runtime中也有1个main( )函数runtime.main,代码经过编译后,runtime.main会调用main.main,程序启动时会为runtime.main创建Goroutine,称为Main Goroutine,然后把Main Goroutine加入P的本地队列,如图所示
(4)启动M0,M0已经绑定了P,会从P的本地队列获取G,并获取Main Goroutine。
(5)G拥有栈,M根据G中的栈信息和调度信息设置运行环境。
(6)M运行G。
(7)G退出,再次回到M获取可运行的G,这样重复下去,直到main.main退出,runtime.main执行Defer和Panic处理,或调用runtime.exit退出程序。
调度器的生命周期几乎占满了一个Go程序的一生,runtime.main的Goroutine执行之前都是为调度器做准备工作,runtime.main的Goroutine运行才是调度器的真正开始,直到runtime.main结束而结束。
本文作者:曹子昂
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!