The signal mask is calculated and installed only for the duration of
the signal handler.By default,the signal “sig” is also blocked when the signal occurs.
Once an action is installed for a specific signal using sigaction,
it remains installed until another action is explicitly requested.
这是否意味着在从信号处理程序返回后恢复默认信号掩码?
另外,使用后我是否必须重新安装处理程序,就像我使用signal()一样?
还有,这段代码:
#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> void termination_handler(int signum) { exit(7); } int main (void) { struct sigaction new_action,old_action; new_action.sa_handler = termination_handler; sigemptyset(&new_action.sa_mask); sigaddset(&new_action.sa_mask,SIGTERM); new_action.sa_flags = 0; sigaction(SIGINT,NULL,&old_action); if (old_action.sa_handler != SIG_IGN) { sigaction(SIGINT,&new_action,NULL); } sleep(10); return 0; }
那么 – SIGTERM将如何处理?我可以看到已安装的处理程序是终止处理程序(),但随后SIGTERM被添加到信号掩码而不使用sigprocmask().这是什么意思?谢谢!
附:最后一个问题:为什么main()中的if语句?
解决方法
#include <signal.h> #include <stdio.h> void termination_handler(int signum) { printf("Hello from handler\n"); sleep(1); } int main (void) { //Structs that will describe the old action and the new action //associated to the SIGINT signal (Ctrl+c from keyboard). struct sigaction new_action,old_action; //Set the handler in the new_action struct new_action.sa_handler = termination_handler; //Set to empty the sa_mask. It means that no signal is blocked // while the handler run. sigemptyset(&new_action.sa_mask); //Block the SEGTERM signal. // It means that while the handler run,the SIGTERM signal is ignored sigaddset(&new_action.sa_mask,SIGTERM); //Remove any flag from sa_flag. See documentation for flags allowed new_action.sa_flags = 0; //Read the old signal associated to SIGINT (keyboard,see signal(7)) sigaction(SIGINT,&old_action); //If the old handler wasn't SIG_IGN (it's a handler that just // "ignore" the signal) if (old_action.sa_handler != SIG_IGN) { //Replace the signal handler of SIGINT with the one described by new_action sigaction(SIGINT,NULL); } while(1) { printf("In the loop\n"); sleep(100); } return 0; }
因此,如果您编译并启动它,然后按Ctrl C,那么您将执行处理程序消息,然后您立即返回主要的睡眠状态.您可以根据需要多次执行此操作,并且仍会显示处理程序消息和内联消息.
因此,您提供了一个函数,sigaction会执行将信号与处理程序挂钩所需的所有操作.
现在,sigterm怎么样?如果你在termination_handler中增加了睡眠时间,你可以在按下Ctrl C后键入类似“pkill –signal SIGTERM ./a.out”的内容.然后,会发生什么?没有!在termination_handler运行时,SIGTERM信号被阻止.但是一旦你回到主,现在SIGTERM将杀死应用程序.
(请记住,在测试此代码时,您仍然可以通过发送SIGKILL信号来终止应用程序.)
如果你想了解更多,并且对信号有更多的乐趣,你可以使用signal manual和sigaction manual来说明更多信息.请注意,您还具有sigaction结构的详细说明.