基于Libtask进行协程浅析

协程介绍与子例程一样,协程也是一种程序组件。 相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛。 协程源自Simula和Modula-2语言,但也有其他语言支持。 协程更适合于用来实现彼此熟悉的程序组件,如合作式多任务,迭代器,无限列表和管道。 –维基百科 下面我们会以Libtask(Go语言的作者之一Russ Cox的作品)作为分析案例来解释协程的原理。协程工作原理要了解协
摘要由CSDN通过智能技术生成

协程介绍

与子例程一样,协程也是一种程序组件。 相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛。 协程源自Simula和Modula-2语言,但也有其他语言支持。 协程更适合于用来实现彼此熟悉的程序组件,如合作式多任务,迭代器,无限列表和管道。 –维基百科
下面我们会以Libtask(Go语言的作者之一Russ Cox的作品)作为分析案例来解释协程的原理。

协程工作原理

要了解协程的工作原理,可以从以下几点入手:

1、上下文切换。
2、函数调用原理。
3、Libtask保存寄存器值的结构体。
4、Libtask的接口函数和实现。

1、上下文切换
当一个程序被执行(称为进程)的时候,这些寄存器的值通常会被修改。所以当要切换进程执行的时候,只需要把这些寄存器的值保存下来,然后把新进程寄存器的值赋值到CPU中(我们知道CPU的使命就是执行程序中的指令,而且CPU内部有很多用于存放数据的寄存器,其中比较重要的一个寄存器叫EIP寄存器,它用于存储下一条要执行的指令。除了EIP寄存器之外,还有一个比较重要的寄存器叫ESP寄存器,它用于保存程序的栈顶位置。除此之外,CPU还有很多其他用途的寄存器,如:通用寄存器EAX、EDX和段寄存器CS、DS等等。),那么就完成进程切换了,通常我们把这个过程称为上下文切换,协程的切换也类似。

2、函数的调用原理
以C语言为例,函数调用时通过栈结构来保存现场和恢复现场的。比如,在第189行有这样一段代码来进行函数调用:demoFunc(a, b, c, d);那么,第190行代码的地址会被放在栈底,然后,实参从右往左一次入栈。这样一来,当该函数完毕,程序又会恢复到之前调用处(189行)的下一行(190行)。原理如下图(图片来自百度):这里写图片描述

3、Libtask保存寄存器值的结构体
前面说过,要进行上下文切换,存储对应寄存器的值是必不可少的。Libtask通过引进struct mcontext这个结构体来保存对应的寄存器的值,以下是struct mcontext这个结构体的源码实现,命名比较规范,感兴趣的读者

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值