使用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语句用于比较(检查捕获信号应为一个)。第一个问题的答案取决于“信号处理器的持续时间”。