c alarm()和pause()导致永久停顿

时间:2012-11-27 17:12:55

标签: 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 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);
}

这是输出,最后一行显示应用程序暂停的位置

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

2 个答案:

答案 0 :(得分:4)

使用sigsetjmp()siglongjmp()来保存和恢复信号掩码(默认情况下不会在Linux中保存),以清除来自人setjmp()的任何待处理信号:

  

POSIX没有指定setjmp()是否会保存信号掩码。在System V中它不会。默认情况下,Linux / glibc遵循System V行为。 如果要移植保存和恢复信号掩码,请使用sigsetjmp()   和siglongjmp()

注意:我不确定你要完成什么,但是你的代码看起来应该在无限循环中运行,调用longjmp()恢复执行就好像它刚刚从{{1它会永远持续下去。

答案 1 :(得分:0)

根据http://linux.die.net/man/2/pause

  

pause()仅在捕获到信号且信号捕获时返回   函数返回

在你的情况下它永远不会返回,它会longjmp输出。