13
#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"时都应打印"Into handler " 。

我想在“SIGINT handler()”本身中捕获 SIGINT..

4

5 回答 5

12

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

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

于 2010-03-10T17:15:41.077 回答
8

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

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

从信号处理程序调用printf是未定义的行为。它可能会使您的程序崩溃。您实际上可以从信号处理程序安全调用的函数列表非常有限。我需要来自 glibc 的异步信号安全函数列表

于 2010-03-10T17:05:33.723 回答
3

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

此外,您需要while用更强大的东西替换循环,作为在测试信号处理程序时退出程序的一种方式......比如......你如何退出它?

于 2010-03-10T17:17:49.647 回答
2

您可以使用类似这样的东西来代替 printf:

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

write(..)从信号处理程序调用该函数是安全的。不要忘记包含unistd.h标题以使用它。

于 2014-12-19T10:31:54.627 回答
1

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

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

于 2010-03-10T17:02:00.157 回答