理解无栈协程

c++20加入了协程,为了性能实现的是无栈协程。有栈协程与无栈协程有栈协程与无栈协程对协程的两种实现做了介绍,简单来说有栈协程是可以中断并恢复执行的subroutine,无栈协程是状态机。
使用 C 语言实现协程中介绍的这个无栈协程实现可以帮助更好的理解为什么说无栈协程是状态机。

coroutine.h只用三个宏(这里有简化)就实现了一个不可重入的无栈协程:

#pragma once
#define coBegin     static int _SCRLINE=0; switch(_SCRLINE) { case 0:
#define coReturn(z) { _SCRLINE=__LINE__; return (z); case __LINE__:; }
#define coFinish(z) } return (z)

用一个例子来了解它的实现:

int fibonacci()
{
    static int a=1, b=1;
    coBegin;
    coReturn(1);
    coReturn(1);
    for(;;)
    {
        b += a;
        a = b - a;
        coReturn(b);
    }
    coFinish(0);
}

这个函数用来计算斐波那契数列,把宏展开等价于:

int fibonacci()
{
    static int a=1, b=1;
    static int state=0;
    switch(state)
    {
        case 0:
              {state=1;
               return 1;
        case 1:;}
              {state=2;
               return 1;
        case 2:;}
               for(;;)
               {
                   b += a;
                   a = b - a;
                  {state=3;
                   return b;
        case 3:;}
               }
    }
    return 0;
}

这里需要说明下switch case语句,case语句属于Labeled statements,就是goto后边的那个标签,任何一条语句都能在自己前面声明一个标识符作为标签名称,标签本身并不会改变控制流。所以case放在{}中或for循环中是没问题的。case 3后面跟了一条空语句是因为标签后面得有一条语句。
coReturn带有{}是为了支持跟在if语句后且没被{}包裹的情况。
c语言里的循环,可以认为是goto语句的语法糖,例如:

int test()
{
    int sum = 0;
    for(int i=0; i<10; ++i)
        sum += i;
    return sum;
}

int test()
{
    int sum = 0;
    {
        int i=0;
loop:
        if(i<10)
        {
            sum += i;
            ++i;
            goto loop;
        }
    }
    return sum;
}

是完全等价的。所以fibonacci就可以改写为:

int fibonacci()
{
    static int a=1, b=1;
    static int state=0;
    switch(state)
    {
        case 0:
               state=1;
               return 1;
        case 1:
               state=2;
               return 1;
        case 2:
        loop:
               b += a;
               a = b - a;
               state=3;
               return b;
        case 3:
               goto loop;
    }
    return 0;
}

这个状态机就很明显了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值