继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

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

慕九州9237533
关注TA
已关注
手记 43
粉丝 2
获赞 4

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


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


课程讲师:Moody


课程内容:

    http://img1.mukewang.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方法,这个方法是平台相关的。


  • http://img3.mukewang.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方法,完成一个循环


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP