使用sigaction(),c
我正在读一点关于使用sigaction(),c,c,unix,signals,bitmask,systems-programming,C,Unix,Signals,Bitmask,Systems Programming,我正在读一点关于sigaction()(来源于我的课程笔记)的书,我不确定我是否理解了这篇文章: 仅在以下时间内计算并安装信号屏蔽: 信号处理器 默认情况下,当信号出现时,信号“sig”也被阻断 使用sigaction为特定信号安装操作后, 在明确请求另一个操作之前,它将保持安装状态 这是否意味着从信号处理程序返回后会恢复默认信号掩码? 此外,我是否必须在使用处理程序后重新安装它,就像我使用的是signal() 还有一段代码: #include <signal.h> #include
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;
}
#包括
#包括
#包括
#包括
无效终止处理程序(int信号){
出口(7);
}
内部主(空){
结构sigaction新动作、旧动作;
new_action.sa_handler=终止_handler;
SIGEPTYSET(和新的_action.sa_mask);
sigaddset(&new_action.sa_mask,SIGTERM);
新建_action.sa_标志=0;
sigation(SIGINT、NULL和old_操作);
if(旧的\u action.sa\u处理程序!=SIG\u IGN){
sigaction(SIGINT和new_action,NULL);
}
睡眠(10);
返回0;
}
那么-如何准确处理SIGTERM
?我可以看到安装的处理程序是termination handler()
,但随后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, 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;
}
#包括
#包括
无效终止处理程序(int信号)
{
printf(“来自处理程序的Hello\n”);
睡眠(1);
}
内部主(空)
{
//将描述旧操作和新操作的结构
//与SIGINT信号关联(键盘上的Ctrl+c)。
结构sigaction新动作、旧动作;
//在新的动作结构中设置处理程序
new_action.sa_handler=终止_handler;
//设置为清空sa_掩码。这意味着没有信号被阻止
//当处理程序运行时。
SIGEPTYSET(和新的_action.sa_mask);
//阻断SEGTERM信号。
//这意味着当处理程序运行时,SIGTERM信号被忽略
sigaddset(&new_action.sa_mask,SIGTERM);
//从SAU标志中删除任何标志。有关允许的标志,请参阅文档
新建_action.sa_标志=0;
//读取与SIGINT相关的旧信号(键盘,参见信号(7))
sigation(SIGINT、NULL和old_操作);
//如果旧处理程序不是SIG_IGN(它是一个
//“忽略”信号)
if(旧的\u action.sa\u处理程序!=SIG\u IGN)
{
//用new_action描述的信号处理程序替换SIGINT的信号处理程序
sigaction(SIGINT和new_action,NULL);
}
而(1)
{
printf(“在循环中\n”);
睡眠(100);
}
返回0;
}
因此,如果您编译并启动它,然后按Ctrl+C,那么您将执行处理程序消息,然后立即从main的睡眠中恢复。您可以根据需要多次执行此操作,处理程序消息和inloop消息仍会显示 因此,您给出了一个函数,sigaction完成了将信号与处理程序挂钩所需的一切工作
现在,sigterm呢?如果在终止处理程序中增加睡眠时间,可以在按Ctrl+C后键入类似“pkill--signal SIGTERM./a.out”的内容。然后,会发生什么?没有什么!SIGTERM信号在终端处理程序运行时被阻止。但是一旦你回到主界面,现在SIGTERM将终止应用程序 (请记住,在测试此代码时,仍然可以通过发送SIGKILL信号来终止应用程序。)
如果你想知道更多,并对信号有更多的乐趣,你就有了和,它告诉了你更多。请注意,您还拥有sigaction结构的详细描述。您是否使用过自己的信号处理程序?如果没有,我的建议是首先使用您自己的信号处理器。这样,sigaction就很容易理解了。İf语句用于比较(检查捕获信号应为一个)。第一个问题的答案取决于“信号处理器的持续时间”。