代码之家  ›  专栏  ›  技术社区  ›  JustWe

如何在C中实现for循环内的协程

  •  1
  • JustWe  · 技术社区  · 6 年前

    以下是零件代码:

    void a()
    {
        printf("entering a\n");
        int i;
        for(i = 0; i < 3; i++){
            if(setjmp(a_buf) == 0) {
                printf("A step %d\n", i);
                b();
            } else {
                longjmp(b_buf, 1);
            }
        }
        printf("returning from a\n");
    }
    
    void b()
    {
        printf("entering b\n");
        int i;
        for(i = 0; i < 5; i++){
            if(setjmp(b_buf) == 0) {
                printf("B step %d\n", i);
                a();
            } else {
                longjmp(a_buf, 1);
            }
        }
        printf("returning from b\n");
    }
    

    我有两个过程 a 和; b . 如何使它们作为协同程序工作。 希望他们做 A Step 0 然后 B Step 0 然后回到 A Step 1 …直到两者都结束。但看起来像柜台 i 从未改变。

    2 回复  |  直到 6 年前
        1
  •  3
  •   Ajay Brahmakshatriya    6 年前

    这里没有定义您试图使用代码实现的目标。

    报价 C11 ,第章 §7.13.2.1p2

    这个 longjmp 函数恢复最近调用 setjmp 宏在程序的同一调用中使用相应的jmp_buf参数。如果没有这样的调用,或者调用来自另一个执行线程, 或者如果函数包含 塞特姆 宏已终止执行 在过渡期间,或者如果调用 塞特姆 宏在具有可变修改类型的标识符的作用域内,并且执行过程中已离开该作用域,行为未定义。

    重点地雷

    关于终止执行的计算:

    报价 C11 ,第章 §note248

    例如,通过执行一个RETURN语句或 朗吉姆普 呼叫已导致传输到 塞特姆 在嵌套调用集的前面的函数中调用。

    所以,假设你打电话来 a() 首先,它调用 b() 在设置 a_buf . 现在 b-() 设置 b_buf 然后跳回到 a . 在这一点上 b 的执行已终止,如果您跳回到 比布夫 ,行为未定义。

    对于您的问题,一个可能的解决方案是定义函数 a_step() b_step() 它只执行一个步骤 () b-() 分别。然后在循环中交替调用它们。

        2
  •  3
  •   gone    6 年前

    这个 setjmp() longjmp() 函数只能作为一种“throw/catch”从嵌套子例程中退出。它们不能用于重新输入已经退出的子程序,或者通过 return 或者通过 长jmp() . 简而言之,它们不能这样使用。

    在C中实现协程的唯一定义良好的方法是 as a state machine . 无法将协同程序实现为普通子例程,因为这与C堆栈不兼容。