如何在c中的for循环中实现协同程序

时间:2018-05-23 06:58:17

标签: c coroutine

以下是部分代码:

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&amp; b。如何使它们像协程一样工作。 希望他们A Step 0然后B Step 0然后回到A Step 1 ......直到两个完成。但看起来计数器i从未改变过。

2 个答案:

答案 0 :(得分:3)

您在此处尝试使用代码实现的目标尚未定义。

引用C11,章§7.13.2.1p2

  

longjmp函数在相同的程序调用中使用相应的jmp_buf参数恢复最近调用setjmp宏所保存的环境。如果没有这样的调用,或者调用来自另一个执行线程,或者如果包含setjmp宏调用的函数在此期间终止执行,或者如果setjmp宏的调用是在具有可变修改类型的标识符的范围内,并且执行已将该范围留在过渡期间,行为未定义。

     

强调我的

关于什么算作终止执行:

引用C11,章§note248

  

例如,通过执行return语句或因为另一个longjmp调用导致转移到嵌套调用集合中较早的函数中的setjmp调用。

因此,请先说a(),然后在设置b()后调用a_buf。现在b()设置b_buf并跳回a。此时b的执行已终止,如果您跳回b_buf,则行为未定义。

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

答案 1 :(得分:0)

请查看“ s_task”协程,这可能是您的答案-

https://github.com/xhawk18/s_task

功能-

  1. 用纯c和asm编写,不需要c ++
  2. 来自Boost上下文的
  3. asm代码,功能强大且有效
  4. 添加关键字等待异步
  5. 支持各种平台,例如Windows,Linux(arm,x86,mips),stm32,stm8
  6. 已与libuv集成以进行网络编程
  7. “事件”和“互斥体”对象,用于信息之间的通信