使用sigaction(),c

yot*_*moo 6 c unix signals bitmask systems-programming

我正在做一些阅读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;
}
Run Code Online (Sandbox Code Playgroud)

那么 - 究竟将如何SIGTERM处理?我可以看到安装的处理程序是termination handler(),但随后SIGTERM被添加到信号掩码而没有使用sigprocmask().这是什么意思?谢谢!

Ps最后一个问题:为什么if声明在main()

Jer*_*hoy 10

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您编译并启动它,然后按Ctrl + C,那么您将执行处理程序消息,然后您立即退回主要的睡眠状态.您可以根据需要多次执行此操作,并且仍会显示处理程序消息和内联消息.

因此,您提供了一个函数,sigaction会执行将信号与处理程序挂钩所需的所有操作.


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

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


如果您想了解更多信息,并获得更多有关信号的乐趣,您可以使用信号手册sigaction手册,它们可以提供更多信息.请注意,您还具有sigaction结构的详细说明.