首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用sigaction(),c

使用sigaction(),c
EN

Stack Overflow用户
提问于 2012-07-13 06:19:24
回答 1查看 14K关注 0票数 8

我正在读一些关于sigaction()的文章(资料来源于我的课程笔记),我不确定我是否理解这篇文章:

仅在信号处理程序的持续时间内计算和安装信号掩码。 默认情况下,信号“sig”在信号发生时也会被阻塞。 一旦使用sigaction为特定信号安装了一个动作,它就会一直被安装,直到另一个动作被显式请求为止。

这是否意味着在从信号处理程序返回后恢复默认的信号掩码?另外,我是否必须在使用处理程序后重新安装它,就好像我使用了signal()一样。

另外,还有一段代码:

代码语言:javascript
复制
#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()。这是什么意思?谢谢!

附注:最后一个问题:为什么if语句在main()

EN

回答 1

Stack Overflow用户

发布于 2013-07-10 14:05:45

让我们试着理解修改后的代码版本所发生的事情:

代码语言:javascript
复制
#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,那么您将执行处理程序消息,然后立即从main的睡眠中恢复。您可以想做多少次就做多少次,并且仍然显示处理程序消息和内循环消息。

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

那么,西格纳特呢?如果您在termination_handler中增加了睡眠时间,您可以在按Ctrl+C之后键入类似于"pkill -SignalSIGTERM.a.out“之类的内容。然后,会发生什么呢?没什么!当termination_handler运行时,SIGTERM信号被阻塞。但是,一旦您返回主,现在SIGTERM将杀死应用程序。

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

如果你想知道更多,并且在信号方面有更多的乐趣,你就有了信号手册印字手册,它们告诉了你更多的信息。请注意,您还拥有sigaction结构的详细描述。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11465148

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档