Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c报警()和暂停()导致永久暂停_C - Fatal编程技术网

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