c-setjmp和longjmp在两个函数之间切换的问题



我正在尝试实现一个代码,它可以在函数fun((和main((之间连续切换,这两个函数除了在屏幕上无限打印之外什么都不做。我试图通过setjmp和longjmp进行切换,并在C中使用SIGALRM信号。但当我运行它时,它只工作一次,然后就不会切换。

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
jmp_buf b1, b2;
int cur = 0;
void handlesig(int sig) {
if(!cur) {
cur = 1;
setjmp(b2);
longjmp(b1, 1);
}
else {
cur = 0;
setjmp(b1);
longjmp(b2, 1);
}
}
void fun() {    
while(1) {
printf("I am in function fun()n");
for(int x = 0; x < 100000000; x++);
}
}
int main() {    
signal(SIGALRM, handlesig);
ualarm(900000, 900000);                     //send SIGALRM after each 900000 microseconds
if(!setjmp(b1))
fun();                                  //will be run when setjmp returns 0
while(1) {                      
printf("I am in function main()n");    //will be run when setjmp returns 1
for(int x = 0; x < 100000000; x++);
}
return 0;
}

我不知道这个代码有什么问题。

您的程序有未定义的行为,因为信号处理程序中在b1b2上调用setjmp的块的生存期在调用longjmp后立即结束(在下一行(。下次调用longjmp试图返回到不再有效的jmp_buf时,行为是未定义的,这表现为状态完全损坏。

您可以编写破解来解决此问题,方法是使用sigaltstackSA_ONSTACK标志使信号处理程序具有多个堆栈,这样即使jmp_buf在形式上无效,但在实践中也不会被破坏。但这不是一个有效的程序,只是一个碰巧在某些系统上运行的程序。最终,对于setjmplongjmp,没有(有效/可靠(的方法可以满足您的要求;上下文切换需要比它们提供的严格更强的原语。

最新更新