栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

理解无栈协程

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

理解无栈协程

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

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

#define scrBegin     static int scrLine=0; switch(scrLine) { case 0:
#define scrReturn(z) { scrLine=__LINE__; return (z); case __LINE__:; }
#define scrFinish(z) } return (z)

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

int fibonacci()
{
    static int a=1, b=1;
    scrBegin;
    scrReturn(1);
    scrReturn(1);
    for(;;)
    {
        b += a;
        a = b - a;
        scrReturn(b);
    }
    scrFinish(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后面跟了一条空语句是因为标签后面得有一条语句。
scrReturn带有{}是为了支持跟在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;
}

这个状态机就很明显了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/743488.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号