2
#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 信号时,它没有反应?

4

2 回答 2

4

正如许多评论和回复的那样, \n不要/nprintf格式字符串中使用。或者调用fflush(3)例如fflush(NULL);在你的printf.

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

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

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

另请参阅此答案

于 2013-05-12T13:21:02.163 回答
1

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

于 2013-05-12T09:43:45.240 回答