Using sigaction(), c



我读了一些关于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.最后一个问题:为什么main()中有if语句?

让我们试着了解代码的修改版本发生了什么

#include <signal.h>
#include <stdio.h>
void termination_handler(int signum)
{
    printf("Hello from handlern");
    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 loopn");
        sleep(100);
    }
    return 0;
}

因此,如果您编译并启动它,然后按Ctrl+C,那么您将执行处理程序消息,然后您将立即从main的睡眠中返回。您可以根据需要多次执行此操作,并且处理程序消息和inloop消息仍然显示。

因此,您给出了一个函数,sigaction完成了将信号与处理程序挂钩所需的一切。


现在,sigterm呢?如果您在termination_handler中增加睡眠时间,您可以在按下Ctrl+C后键入类似"pkill--signal SIGTERM./a.out"的内容。那么,会发生什么呢?没有什么termination_handler运行时,SIGTERM信号被阻止。但是,一旦您回到主界面,现在SIGTERM将终止应用程序。

(记住,在测试此代码时,您仍然可以通过发送SIGKILL信号来杀死应用程序。)


如果你想了解更多,并从信号中获得更多乐趣,你有信号手册和sigaction手册,它们讲述了更多。请注意,您还有sigaction结构的详细描述。

最新更新