#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。
答案 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)”阻止第一个服务调用返回。删除它和后续中断应该导致再次调用处理程序。
中断服务程序不应该阻止调用线程返回。