为了账号安全,请及时绑定邮箱和手机立即绑定

【九月打卡】第11天 go的协程(2)

标签:
Go

课程名称:深入Go底层原理,重写Redis中间件实战


课程章节:5-3 协程是如何执行的


课程讲师:Moody


课程内容:

    https://img1.sycdn.imooc.com//632351fa00015ad017601003.jpg

  • schedule,先创建了一个gp *g,g类型的gp,用来存储拿到的协程g。这个方法会去不停尝试拿到一个协程。

    _g_.m.p.ptr().schedtick%61 == 0 && sched.runqsize > 0

    如果当前线程取了61次还没有取到,就去全局队列里拿。

  • execute,这个方法在schedule方法的最末尾执行,传入schedule拿到的gp,开始对gp的一些参数进行赋值。

  • gogo(&gp.sched),gogo方法运行与execute最末尾,是一个汇编方法。每个平台都实现了gogo方法,这个方法是平台相关的。


  • https://img1.sycdn.imooc.com//6323612e0001f59306590798.jpg

  • gogo方法最后会调用汇编的gogo,gogo会在用户的业务代码里插入第一个栈帧,第一个栈帧就是goexit()方法,位于上图汇编的 gobuf_sp

  • gogo方法的末尾会执行 gobuf_pc(BX),这个方法很重要,这个就是gobuf里记录的当前程序运行到哪一行,也就是说,如果发生了协程切换,那么gobuf就会记录程序运行到哪一行,并挂起,等线程再度调起该协程,协程将从上一次执行的位置开始,这个位置就是BX。JMP 命令让程序接着上一次的继续执行,并还原上下文。

  • 最终程序出栈的时候,会退到第一个栈帧,也就是goexit()方法,该方法也是个汇编,其中调用的是runtime包的goexit1()方法。

  • goexit1 方法会调用 mcall(goexit0),mcall会从用户的代码出来,调用g0栈。g0栈运行goexit0方法,传入gp ,gp的各种参数会被恢复到一个状态,并最后调用 schedule方法,完成一个循环


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
PHP开发工程师
手记
粉丝
2
获赞与收藏
4

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消