c报警()和暂停()导致永久暂停
在下面的程序中,“暂停”被中断一次,但“暂停”永远不会返回。我已经设置了中断暂停的警报,所以我很困惑为什么暂停永远不会回来c报警()和暂停()导致永久暂停,c,C,在下面的程序中,“暂停”被中断一次,但“暂停”永远不会返回。我已经设置了中断暂停的警报,所以我很困惑为什么暂停永远不会回来 #include <setjmp.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> static void sig_alrm(int); static jmp_buf env_alrm; int
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
static void sig_alrm(int);
static jmp_buf env_alrm;
int main(int arc, char **argv)
{
int x;
x = setjmp(env_alrm);
printf("setjmp was created with return value: %d\n", x);
if(signal(SIGALRM, sig_alrm) == SIG_ERR)
{
printf("Error settting SIGALRM\n");
exit(1);
}
if((x!= 0) && (x!=1))
{
printf("Error setting setjmp\n");
exit(1);
}
printf("Line next to setjmp\n");
x = alarm(2);
printf("Alarm set for 2 seconds, remaning secs from previous alarm: %d\n");
pause();
printf("Line next to pause()\n");
alarm(0);
return 0;
}
static void sig_alrm(int signo)
{
longjmp(env_alrm, 1);
}
根据:
pause()仅在捕捉到信号且捕捉到信号时返回
返回函数
在您的情况下,它永远不会返回,它会执行longjmp
输出。使用sigsetjmp()
和siglongjmp()
来保存和恢复信号掩码,这些掩码在Linux中默认情况下不会保存,以从man清除任何挂起的信号:
POSIX没有指定setjmp()是否将保存信号掩码。在SystemV中不会。默认情况下,Linux/glibc遵循SystemV行为如果您希望可移植地保存和恢复信号掩码,请使用sigsetjmp()
和siglongjmp()
注意:我不确定您要完成什么,但您的代码看起来应该在无限循环中运行,调用
longjmp()
将恢复执行,就像它刚从setjmp()返回一样,并且它将永远继续运行。好的,在这种情况下,它应该每2秒执行一次longjmp,因为SIGALRM会每2秒发射一次..但这不是观察到的行为。该应用程序在第一次测试之后什么也不做longjmp@Jimm,当跳转到您从未返回的信号处理程序时,信号被阻止。通过在setjmp
之前获取信号掩码,然后恢复,可以获得预期的行为。这样做的安全方法是使用sigsetjmp
。我只是想了解为什么程序在第二次调用alarm后从未像我的输出中所示返回?信号处理程序会阻止更多信号。由于您从未退出信号处理程序(通过正常方式),因此您永远不会得到第二个信号siglongjump
将再次重新启用信号。@ams+1用于解释longjmp()情况下的信号阻塞。@ams可能是,但假设您能够以某种方式清除(解除阻塞)信号,以允许后续信号,如果不恢复信号掩码,这将无关紧要,对吗?@mux,正如您所见,当longjmp返回时,我为SIGALRM重新建立signalhandler。
setjmp was created with return value: 0
Line next to setjmp
Alarm set for 2 seconds, remaining secs from previous alarm: 0
setjmp was created with return value: 1
Line next to setjmp
Alarm set for 2 seconds, remaining secs from previous alarm: 0