使用 longjmp 重新反转控制
reinversion of control using longjmp
我正在尝试使用 longjmp 在 c 中实现控制的重新反转,目前我有以下代码:
#include <stdio.h>
#include <setjmp.h>
jmp_buf env;
int arg;
typedef void (*fptr)(int);
fptr callback;
void cb(int a)
{
arg = a;
longjmp(env, 1);
}
#define cont1(f, x) do { if(!setjmp(env)) { f(x, &cb); return; } } while(0)
void callback_func(int num, fptr cb)
{
printf("in a func, num = %d\n", num);
callback = cb;
}
void task1()
{
printf("before continuation\n");
cont1(callback_func, 7);
printf("after continuation\n");
}
void task2()
{
printf("in thread 2\n");
(*callback)(5);
}
int main()
{
task1();
task2();
printf("arg = %d\n", arg);
return 0;
}
我的问题是:这不会调用未定义的行为或者可能在实际使用中导致任何问题吗?如果是,那么有没有更好的方法来做到这一点?
这个程序有未定义的行为。参见 C11 7.13.2.1 longjmp 函数(强调我的):
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 the setjmp macro has terminated execution248 in the interim, or if the invocation of the setjmp 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.
248) For example, by executing a return statement or because another longjmp call has caused a transfer to a setjmp invocation in a function earlier in the set of nested calls.
在您 cb
调用 longjmp
时,调用 setjmp
填充 env
、task1
的函数已经返回。因此调用 longjmp
是未定义的。
C 语言没有办法做你想做的事情,除了(现在使用 C11)线程,使用条件变量来控制哪个线程运行。
我正在尝试使用 longjmp 在 c 中实现控制的重新反转,目前我有以下代码:
#include <stdio.h>
#include <setjmp.h>
jmp_buf env;
int arg;
typedef void (*fptr)(int);
fptr callback;
void cb(int a)
{
arg = a;
longjmp(env, 1);
}
#define cont1(f, x) do { if(!setjmp(env)) { f(x, &cb); return; } } while(0)
void callback_func(int num, fptr cb)
{
printf("in a func, num = %d\n", num);
callback = cb;
}
void task1()
{
printf("before continuation\n");
cont1(callback_func, 7);
printf("after continuation\n");
}
void task2()
{
printf("in thread 2\n");
(*callback)(5);
}
int main()
{
task1();
task2();
printf("arg = %d\n", arg);
return 0;
}
我的问题是:这不会调用未定义的行为或者可能在实际使用中导致任何问题吗?如果是,那么有没有更好的方法来做到这一点?
这个程序有未定义的行为。参见 C11 7.13.2.1 longjmp 函数(强调我的):
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 the setjmp macro has terminated execution248 in the interim, or if the invocation of the setjmp 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.
248) For example, by executing a return statement or because another longjmp call has caused a transfer to a setjmp invocation in a function earlier in the set of nested calls.
在您 cb
调用 longjmp
时,调用 setjmp
填充 env
、task1
的函数已经返回。因此调用 longjmp
是未定义的。
C 语言没有办法做你想做的事情,除了(现在使用 C11)线程,使用条件变量来控制哪个线程运行。