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

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

最佳答案

正如许多人评论和回复的那样,在 printf 格式字符串中使用 \n 而不是 /n。或调用fflush(3)例如在 printf 之后添加 fflush(NULL);

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

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

如果使用某些事件循环,则使用 Qt 建议的技巧就是创建一些pipe(2)在程序开始附近,轮询事件循环中的管道 - 例如通过使用 poll(2) ,并发送至write(2)进入信号处理程序中的管道(write 是异步信号安全的!)。

另请参阅this answer .

关于c - 为什么我的 Linux 信号处理程序对信号没有反应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16505988/

相关文章:

linux - 修改IOCTL函数调用(ioctl的定义在哪里)来翻转GPIO管脚

c# - 在 Linux 上查看 dotnetcore 2 自包含应用程序的内存使用情况统计信息

c - 在C中实现字符串复制函数

c - 在 C 的 header 中使用 "#define"

c - 写入宽字符流

c - 向进程组中除自身以外的所有进程发送信号

c++ - 如何忽略前 50 秒的信号?

c - 算术 double 表达式和 c/c++

linux - 无法从 putty 配置 tool.sh

c++ - Linux 中使用 sigaction (C++) 的信号处理程序