在自己的处理程序中捕获信号

时间:2010-03-10 16:58:20

标签: c unix posix signals sigint

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

void handler(int signo)
{
    printf("Into handler\n");
    while(1);
}
int main()
{
    struct sigaction act;
    act.sa_handler = handler;
    act.sa_flags = 0;
    sigemptyset(& act.sa_mask);
    sigaction(SIGINT, &act, NULL);
    while(1);
    return 0;
}

在捕获 KeyboardInterrupt 一次后,当我再次按“Ctrl + C”时,不处理SIGINT ... 我打算每次按“Ctrl + C”时打印“进入处理程序”

我想在“SIGINT handler()”本身内捕获SIGINT。

5 个答案:

答案 0 :(得分:10)

您需要在sa_mask上设置SA_NODEFER以捕获与您当前正在处理的信号相同的信号:

  

SA_NODEFER:不要阻止从自己的信号处理程序中接收信号。 SA_NOMASK是此标志的过时非标准同义词。

答案 1 :(得分:6)

你正在做的事情似乎是一个非常糟糕的主意,而且最好只从处理程序设置一个标志并从中返回,然后从main进行打印。

您需要设置SA_NODEFER或以其他方式重新启用信号处理程序本身内的信号,否则信号会在调用处理程序之前被阻止或切换回其默认行为。

从信号处理程序调用{​​{1}}是未定义的行为。它可能会使您的程序崩溃。实际上可以安全地从信号处理程序调用的函数列表非常有限。 I need a list of Async-Signal-Safe Functions from glibc

答案 2 :(得分:3)

在信号处理程序中使用printf函数不是完全一个好主意,因为它可能会导致未定义的行为!代码示例缺少信号处理程序工作的重要位...在 Q6上查看我的博客here。如何捕获分段错误?'

此外,您需要将while循环替换为更强大的东西,以便在测试信号处理程序时退出程序...就像......您如何退出?

答案 3 :(得分:2)

您可以使用类似这样的内容而不是printf:

const char *str = "Into handler\n";
write(1, str, strlen(str));

从信号hanlder调用函数write(..)是安全的。 不要忘记使用unistd.h标题来使用它。

答案 4 :(得分:1)

处理程序中的“while(1)”阻止第一个服务调用返回。删除它和后续中断应该导致再次调用处理程序。

中断服务程序不应该阻止调用线程返回。