使用 sigaction(), c [英] Using sigaction(), c

查看:28
本文介绍了使用 sigaction(), c的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读有关 sigaction()(来源来自我的课程笔记)但我不确定我是否理解这段文字:

I was doing a little reading about sigaction() (sources are from my course notes) and I'm not sure I understand this text:

信号掩码仅在持续时间计算和安装信号处理程序.

The signal mask is calculated and installed only for the duration of the signal handler.

默认情况下,信号sig"也会在信号发生时被阻塞.

By default, the signal "sig" is also blocked when the signal occurs.

一旦使用 sigaction 为特定信号安装了操作,在明确请求另一个操作之前,它会保持安装状态.

Once an action is installed for a specific signal using sigaction, it remains installed until another action is explicitly requested.

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

Does this mean that the default signal mask is restored after returning form the signal handler? Also, do I have to re-install the handler after using it, as if I was using 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().这是什么意思?谢谢!

So - how exactly will SIGTERM be handled? I can see that the installed handler is termination handler(), but then SIGTERM was added to the signal mask with no use of sigprocmask(). What does this mean? Thanks!

附言最后一个问题:为什么 main() 中的 if 语句?

P.s. one last question: why the if statement in main()?

推荐答案

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

Let's try to understand what's happening with a modified version of your code :

#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,那么您将执行处理程序消息,然后您立即从主程序的睡眠状态中返回.您可以根据需要执行多次,并且仍会显示处理程序消息和内循环消息.


So, if you compile it and launch it, and press Ctrl+C, then you'll have the handler message executed, and then you get back immediately out of the main's sleep. You can do it as many time as you want, and the handler message and the inloop message are still displayed.

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

So, you give a function, and sigaction does everything needed to hook the signal with your handler.

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

Now, what about sigterm? If you increase the sleep time in termination_handler, you can type something like "pkill --signal SIGTERM ./a.out" after pressing Ctrl+C. Then, what happens? Nothing! The SIGTERM signal is blocked while termination_handler is running. But once you are back in the main, now the SIGTERM will kill the application.

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

(Remember, while you are testing this code, you can still kill applications by sending a SIGKILL signal.)

如果您想了解更多信息,并从信号中获得更多乐趣,您可以查看 信号手册信号手册这告诉了更多.请注意,您还拥有 sigaction 结构的详细说明.

If you want to know more, and have more fun with signals, you have the signal manual and the sigaction manual which tell a lot more. Notice that you also have the detailed description of the sigaction structure.

这篇关于使用 sigaction(), c的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆