我正在做一些关于sigaction()
的阅读(来自我的课程笔记)并且我不确定我理解这个文字:
仅在持续时间内计算并安装信号掩码 信号处理程序。
默认情况下,当信号出现时,信号“sig”也会被阻止。
使用sigaction为特定信号安装操作后, 它会一直安装,直到明确请求另一个操作。
这是否意味着在从信号处理程序返回后恢复默认信号掩码?
另外,使用后我是否必须重新安装处理程序,就像我使用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
究竟会如何处理?我可以看到已安装的处理程序为termination handler()
,但后来SIGTERM
被添加到信号掩码中而没有使用sigprocmask()
。这是什么意思?谢谢!
P.S。最后一个问题:为什么if
中的main()
语句?
答案 0 :(得分:9)
让我们试着了解修改后的代码版本会发生什么:
#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, NULL, &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,&new_action,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结构的详细说明。