问题
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
longjmp
function restores the environment saved by the most recent invocation of thesetjmp
macro 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 thesetjmp
macro has terminated execution in the interim, or if the invocation of thesetjmp
macro 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
longjmp
call has caused a transfer to asetjmp
invocation 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