如何在c中的for循环中实现协同程序
这是部分代码:
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
永远不会改变。
您在此处使用代码尝试实现的目标尚未定义。
引用C11
,章节§7.13.2.1p2
longjmp
函数在相同的程序调用中使用相应的jmp_buf参数恢复最近调用setjmp
宏所保存的环境。 如果没有这样的调用,或者调用来自另一个执行线程, 或者包含setjmp
宏调用的函数在临时中终止执行 ,或者setjmp
宏的调用是否在具有可变修改类型和执行的标识符在此期间保留该范围,行为未定义。强调我的
关于什么算作终止执行:
引用C11
,章节§note248
例如,通过执行return语句或因为另一个
longjmp
调用导致在嵌套调用集合中较早的函数中转移到setjmp
调用。
所以,假设您首先调用a()
,并在设置a_buf
后调用b()
。 现在b()
设置b_buf
并跳回到a
。 此时b
的执行已经终止,如果你跳回到b_buf
,行为是未定义的。
解决问题的一种可能方法是定义函数a_step()
和b_step()
,它们分别只执行a()
和b()
的单个步骤。 然后在循环中交替调用它们。
setjmp()
和longjmp()
函数只能用于从嵌套子例程中退出,作为一种“throw / catch”。 它们不能用于通过return
或通过longjmp()
重新输入已经退出的子例程。 简而言之,它们不能以这种方式使用。
在C中实现协程的唯一明确定义的方法是作为状态机 。 没有办法将协程实现为普通子例程,因为这与C堆栈不兼容。