前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >意犹未尽 —— GPM 的状态流转(十)

意犹未尽 —— GPM 的状态流转(十)

作者头像
梦醒人间
发布2019-09-10 14:13:08
1.1K0
发布2019-09-10 14:13:08
举报
文章被收录于专栏:码农桃花源

最开始的时候,我们讲了 GPM 到底是什么,当时没有看过太多源码,所以对 GPM 没有一个整体上的认识。

现在我们终于到了快要结束的时候,可以从宏观上总结一下 GPM,这篇文章尝试从它们的状态流转角度总结。

首先是 G 的状态流转:

图上除了 park_m 和 ready 这一块外其他都有涉及。这一对函数在前面讲 channel 的时候有提到,后面我们有机会再单独说一下这部分。

上图省略了一些垃圾回收的状态,毕竟这个系列没有讲这一块。完整的状态流转图可以到参考资料【欧神 调度器初始化】里看。

接着是 P 的状态流转:

通常情况下(在程序运行时不调整 P 的个数),P 只会在上图中的四种状态下进行切换。当程序刚开始运行进行初始化时,所有的 P 都处于 _Pgcstop 状态, 随着 P 的初始化( runtime.procresize),会被置于 _Pidle。 当 M 需要运行时,会 runtime.acquirep 来使 P 变成 Prunning 状态,并通过 runtime.releasep 来释放。 当 G 执行时需要进入系统调用,P 会被设置为 _Psyscall, 如果这个时候被系统监控抢夺( runtime.retake),则 P 会被重新修改为 _Pidle。 如果在程序运行中发生 GC,则 P 会被设置为 _Pgcstop, 并在 runtime.startTheWorld 时重新调整为 _Prunning

上面这段引用自【欧神 调度器初始化】。

最后,我们来看 M 的状态变化:

M 只有自旋和非自旋两种状态。自旋的时候,会努力找工作;找不到的时候会进入非自旋状态,之后会休眠,直到有工作需要处理时,被其他工作线程唤醒,又进入自旋状态。

这是调度器系列的最后一篇文章了。整个系列的核心在于:

  1. GPM 的初始化;
  2. M 是怎样一步步找工作;
  3. 用户栈和 g0 栈的切换;
  4. schedule 的调度循环是怎样运转的;
  5. 监控线程做了什么。

其他和 GC 相关的,我们暂时并未涉及到,留到后续再探索。

调度器的探索我们就要告一段落了,感谢陪伴。

参考资料

【欧神 调度器初始化】https://github.com/changkun/go-under-the-hood/blob/master/book/zh-cn/part2runtime/ch06sched/init.md

【Go 夜读 boya】https://reading.developerlearning.cn/reading/12-2018-08-02-goroutine-gpm/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农桃花源 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档