关于捕捉Unix信号的问题
以下代码仅捕获一次SIGINT信号,然后中断程序存在:关于捕捉Unix信号的问题,unix,signals,Unix,Signals,以下代码仅捕获一次SIGINT信号,然后中断程序存在: #include <signal.h> #include <stdio.h> void IntHandler(int value); void CatchIntSignal() { struct sigaction intAction; intAction.sa_handler = IntHandler; sigemptyset(&intAction.sa_mask); i
#include <signal.h>
#include <stdio.h>
void IntHandler(int value);
void CatchIntSignal()
{
struct sigaction intAction;
intAction.sa_handler = IntHandler;
sigemptyset(&intAction.sa_mask);
intAction.sa_flags = 0;
//if to uncomment any of "0" or "SIG_IGN" - IntHandler will be never called:
//intAction.sa_sigaction = 0/*SIG_IGN*/;
if(sigaction(SIGINT, &intAction, NULL) != 0)
{
printf("sigaction() failed.\n");
}
}
void IntHandler(int value)
{
printf("IntHandler(%d)\n", value);
//uncommenting this does not help:
//CatchIntSignal();
}
int main()
{
CatchIntSignal();
getchar();
return 0;
}
我必须如何修改此代码以在SIGINT捕获后保留程序的退出?
如果要将intAction.sa_sigaction设置为0或SIG_IGN,则永远不会调用IntHandler-但为什么?它必须告诉系统有必要调用IntHandler的哪个未定义值?如果我将某个处理程序设置为intAction.sa_sigaction-将调用此处理程序,但不会调用IntHandler。系统如何知道我设置了intAction.sa_sigaction?捕获中断信号并在捕获代码中处理后,需要将处理设置回SIG_DFL
编辑:请忽略。这仅适用于旧的unix信号 捕获中断信号并在捕获代码中进行处理后,需要将处理设置回SIG_DFL 编辑:请忽略。这仅适用于旧的unix信号 您的问题是struct sigaction的sa_处理程序和sa_sigaction字段实际上是同一个字段。引用sigaction2的OSX手册页: 因此,对sau sigaction的赋值将覆盖已设置的处理程序。您应该只设置sau处理程序,而不使用sau sigaction。以下是CatchIntSignal的内容:
void CatchIntSignal()
{
struct sigaction intAction;
intAction.sa_handler = IntHandler;
sigemptyset(&intAction.sa_mask);
intAction.sa_flags = SA_RESTART;
if(sigaction(SIGINT, &intAction, NULL) != 0)
printf("sigaction() failed: %s\n", strerror(errno));
}
您可能需要添加string.h和errno.h的include以获得要编译的strerrorno位。在系统调用失败时触发的错误消息中始终包含strerrorno
更正:在每个ninjalj的标志中添加了SA_RESTART。您的问题是struct sigaction的SA_处理程序和SA_sigaction字段实际上是同一个字段。引用sigaction2的OSX手册页:
因此,对sau sigaction的赋值将覆盖已设置的处理程序。您应该只设置sau处理程序,而不使用sau sigaction。以下是CatchIntSignal的内容:
void CatchIntSignal()
{
struct sigaction intAction;
intAction.sa_handler = IntHandler;
sigemptyset(&intAction.sa_mask);
intAction.sa_flags = SA_RESTART;
if(sigaction(SIGINT, &intAction, NULL) != 0)
printf("sigaction() failed: %s\n", strerror(errno));
}
您可能需要添加string.h和errno.h的include以获得要编译的strerrorno位。在系统调用失败时触发的错误消息中始终包含strerrorno
更正:为每个ninjalj的标志添加了SA_RESTART。您的问题可能是系统调用被中断,因此getchar返回,可能带有EOF。接下来程序要做的就是退出
因此,您可以尝试检查getchar返回的内容,在stdin上重置错误状态,然后再次调用getchar以获取下一个信号。您的问题可能是系统调用被中断,因此getchar返回,可能带有EOF。接下来程序要做的就是退出
因此,您可以尝试检查getchar返回的内容,重置stdin上的错误状态,然后再次调用getchar以获取下一个信号。我不明白您希望程序做什么。是:第一次接收到SIGINT时,调用IntHandler,然后程序退出?或者是:每次接收到SIGINT时,都会调用IntHandler;在getchar返回之前,程序不会退出?我希望这样,我的程序将捕获SIGINT信号,并且在它之后不会退出。这样,在每次Ctrl+C之后,程序都会打印IntHandler2并继续工作。我不明白您希望程序做什么。是:第一次接收到SIGINT时,调用IntHandler,然后程序退出?或者是:每次接收到SIGINT时,都会调用IntHandler;在getchar返回之前,程序不会退出?我希望这样,我的程序将捕获SIGINT信号,并且在它之后不会退出。这样,在每个Ctrl+C程序之后,都会打印IntHandler2并继续工作;这是sigaction优于signal的主要优点。若使用信号,你们将更接近正确。处理程序将自动重置为SIG_DFL,并且有必要在处理程序中重置处理程序。不使用sigaction;这是sigaction优于signal的主要优点。若使用信号,你们将更接近正确。处理程序将自动重置为SIG_DFL,并且有必要在处理程序中重置处理程序。因此OP应该在SA_标志上设置SA_重启,或者在getchar失败时检查EINTR。是的,确实如此。谢谢你,艾伊!我应该记得萨乌。谢谢你指出ninjalj。@Zack,@ninjali-我也应该记得SA_重启。所以OP应该在SA_标志上设置SA_重启,或者在getchar失败时检查EINTR。是的,确实如此。谢谢你,艾伊!我应该记得萨乌。谢谢你指出ninjalj.@Zack,@ninjali-我也应该记得SA_RESTART.Union。。。你向我透露了真相。非常感谢。协会你向我透露了真相。非常感谢。