为什么我的Linux信号处理程序对信号没有反应?

时间:2013-05-12 09:32:59

标签: c linux signals

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

static void pr_mask(const char * string) {
    sigset_t procmask;

    sigprocmask(SIG_SETMASK, NULL, &procmask);

    printf("%s: ", string);
    if(sigismember(&procmask, SIGINT))
        printf("SIGINT ");
    if(sigismember(&procmask, SIGUSR1))
        printf("SIGUSR1 ");
    if(sigismember(&procmask, SIGUSR2))
        printf("SIGUSR2 ");
    if(sigismember(&procmask, SIGTERM))
        printf("SIGTERM ");
    if(sigismember(&procmask, SIGQUIT))
        printf("SIGQUIT ");
    printf("/n");
}

static void sigusr(int signum)
{
    pr_mask("int sigusr");

    if(signum == SIGUSR1)
        printf("SIGUSR1 received/n");
    else if(signum == SIGUSR2)
        printf("SIGUSR2 received/n");
    else
        printf("signal %d received/n", signum);
}

int main(void)
{
    if(signal(SIGUSR1, sigusr) == SIG_ERR) {
        printf("error catching SIGUSR1/n");
        exit(1);
    }

    if(signal(SIGUSR2, SIG_IGN) == SIG_ERR) {
        printf("error ignoring SIGUSR2/n");
        exit(1);
    }

    if(signal(SIGINT, SIG_DFL) == SIG_ERR) {
        printf("error setting SIGINT to default/n");
        exit(1);
    }

    while(1)
        pause();

    exit(0);
}

对于上面的代码,在Linux中编译后我开始像下面那样运行它。

tomxue@ubuntu:~$ ./a.out &
[2] 5554
[1]   Killed                  ./a.out
tomxue@ubuntu:~$ kill -USR1 5554
tomxue@ubuntu:~$ kill -USR2 5554
tomxue@ubuntu:~$ kill -9 5554
[2]+  Killed                  ./a.out

为什么当我发出USR1和USR2信号时,它没有反应?

2 个答案:

答案 0 :(得分:3)

许多评论和回复,请在\n格式字符串中使用/n而非printf。或致电fflush(3),例如在fflush(NULL);之后添加printf

但是,在信号处理程序中调用printf是错误的。请参阅signal(7),其中解释了 async-signal-safe functions printf不是异步信号安全功能)。

实际上,信号处理程序应该更好地设置一些volatile sigatomic_t标志,应该在代码中的一些重要位置进行测试。

如果使用某个事件循环,Qt建议的技巧是在程序开头附近创建一些pipe(2),以在事件循环中轮询该管道-e.g.在您的信号处理程序中使用poll(2)write(2)进入该管道(write是异步信号安全!)。

另见this answer

答案 1 :(得分:1)

您的信号处理工作正常。只是/n不是新行字符。因为您不打印新行,所有输出都保存在缓冲区中。使用KILL信号终止进程时,将丢弃此缓冲区。