问题
Here is part code:
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");
}
I have two processes a & b. How to make them works as coroutine.
Wish them doing A Step 0 then B Step 0 then back to A Step 1... until both finished. But looks like counter i never changed.
回答1:
What you are trying to achieve using your code here is not defined.
Quoting C11, chapter §7.13.2.1p2
The
longjmpfunction restores the environment saved by the most recent invocation of thesetjmpmacro in the same invocation of the program with the corresponding jmp_buf argument. If there has been no such invocation, or if the invocation was from another thread of execution, or if the function containing the invocation of thesetjmpmacro has terminated execution in the interim, or if the invocation of thesetjmpmacro was within the scope of an identifier with variably modified type and execution has left that scope in the interim, the behavior is undefined.Emphasis mine
Regarding what counts as terminated execution:
Quoting C11, chapter §note248
For example, by executing a return statement or because another
longjmpcall has caused a transfer to asetjmpinvocation in a function earlier in the set of nested calls.
So, say you call a() first, and it calls b() after setting the a_buf. Now b() sets the b_buf and jumps back to a. At this point b's execution has terminated and if you jump back to b_buf, the behavior is undefined.
One possible solution for your problem could be to define functions a_step() and b_step() which perform just a single step of a() and b() respectively. Then call them alternatively in a loop.
回答2:
The setjmp() and longjmp() functions can only be used to exit from a nested subroutine, as a sort of "throw/catch". They cannot be used to reenter a subroutine that has already exited, either through a return or through a longjmp(). In short, they cannot be used this way.
The only well-defined way to implement coroutines in C is as a state machine. There is no way to implement coroutines as normal subroutines, as this is incompatible with the C stack.
来源:https://stackoverflow.com/questions/50481755/how-to-implement-coroutine-within-for-loop-in-c