【问题标题】:linux C languang. setjmp longjmp alarmlinux C languang. setjmp longjmp alarm
【发布时间】:2020-08-21 00:35:10
【问题描述】:

execute

my code

jmp_buf a;

void sig_handler(int signum) {
        if(signum == SIGINT) exit(0);

        printf("In the handler\n");
        sleep(2);
        alarm(3);
        longjmp(a,1);
}
int main(int argc, char *argv[]) {
    int j=0;
    struct sigaction sa;

    memset(&sa, 0, sizeof(struct sigaction));
    sa.sa_handler = sig_handler;
    sigfillset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGALRM, &sa, NULL);

    alarm(2);
    j = setjmp(a);
    while(1){
       printf("In the main\n");
       pause();
        }
    return 0;
}

我以为这段代码的结果是

主要是。 在处理程序中。 在主要。 在处理程序中。 在主要。 在处理程序中。 在主要。 在处理程序中。 . . .

但它没有工作。处理程序中未设置警报功能。 当我删除 setjmp、longjmp 时,它运行良好。但我不想删除它们。 setjmp 是否影响设置报警功能?如何解决这个问题。

【问题讨论】:

    标签: c linux alarm setjmp sigaction


    【解决方案1】:

    longjmp 和信号的交互是未指定的。请改用siglongjmp。这段代码应该可以工作:

    #include <stdio.h>
    #include <string.h>
    #include <signal.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <setjmp.h>
    
    sigjmp_buf a;
    
    void sig_handler(int signum) {
            if(signum == SIGINT) exit(0);
    
            printf("In the handler\n");
            sleep(2);
            alarm(3);
            siglongjmp(a,1);
    }
    
    int main(int argc, char *argv[])
    {
        int j=0;
        struct sigaction sa;
    
        memset(&sa, 0, sizeof(struct sigaction));
        sa.sa_handler = sig_handler;
        sigfillset(&sa.sa_mask);
        sa.sa_flags = SA_NODEFER;
        sigaction(SIGALRM, &sa, NULL);
    
        alarm(2);
        j = sigsetjmp(a, 1);
        while(1){
           printf("In the main\n");
           pause();
            }
        return 0;
    }
    

    【讨论】:

    • 该行为实际上是在 Linux 上指定的,根据手册页:它是 System V 风格,setjmp/longjmp 不要触摸信号掩码。所以(@pjlee 的更多信息):在原始程序中,当处理程序启动时,所有信号都被阻止(如传递给 sigaction 的掩码中所要求的)。如果处理程序返回,它们将再次被解除阻塞,但由于您使用longjmp,它们仍然被阻塞。所以当 SIGALRM 第二次到达时,它仍然被阻塞,并且没有调用处理程序。 [...]
    • siglongjmp 确保掩码设置回您调用 sigsetjmp 时的方式,即 SIGALRM 未阻塞。这就是它起作用的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 1970-01-01
    • 2016-03-22
    相关资源
    最近更新 更多