【问题标题】:Why won't this signal handler catch SIGHUP or SIGQUIT?为什么这个信号处理程序不能捕获 SIGHUP 或 SIGQUIT?
【发布时间】:2020-05-20 01:40:31
【问题描述】:

我开始练习处理信号,并想看看我是否可以阻止使用 SIGHUP 或 SIGQUIT 来停止在与 sigaction 结构相同的程序中执行的进程。但是下面的函数似乎并没有阻止我通过命令行发送 SIGHUP 或 SIGQUIT 来停止进程。通过在命令行中输入 $ kill -HUP PID# 或 $ kill -QUIT PID# 将关闭进程。我想通过将我想要阻止的信号添加到掩码中,它会阻止这些信号被传递。使用 sigfillset() 的结果与 sigaddset() 相同。我正在使用 ubuntu。谢谢你的帮助。

【问题讨论】:

    标签: c++ linux


    【解决方案1】:

    我们将首先重新阅读 sa_mask 所做的事情,您设置它的目的是为了阻止有问题的信号,但这并不是 确切可以。

    来自sigaction(2) 手册页:

       sa_mask  specifies  a  mask  of  signals which should be blocked (i.e.,
       added to the signal mask of the thread in which the signal  handler  is
       invoked) during execution of the signal handler.
    

    您在这里阻塞的唯一事情是这些信号在信号处理程序正在执行时。对于在正常业务过程中处理(或阻止)这些信号的目标,它绝对没有任何作用。

    但是,这无关紧要,因为:

    if(execl(argv[1], argv[1], argv[2], argv[3], NULL) == -1) {
    

    显示的代码随后execs 一个新进程。从signal(7) 手册页我们了解信号处理程序会发生什么:

    通过 fork(2) 创建的子节点继承了其父节点的信号显示副本- 职位。在 execve(2) 期间,已处理的处置 信号被重置为默认值;被忽略信号的处置 保持不变。

    显示的代码安装了一个信号处理程序。因此信号处理恢复为默认值,即SIGQUITSIGHUP 的进程终止。

    忽略信号与在信号处理程序执行时阻止它们不同。要了解如何执行此操作,请返回 sigaction(2) 手册页:

    sa_handler 指定要与 signum 关联的操作,并且 可能是默认操作的 SIG_DFL,忽略此操作的 SIG_IGN 信号,或指向信号处理函数的指针。

    您的代码选择了 3 号门,这是一个信号处理函数。您的代码应该选择了门 #2,SIG_IGN

    【讨论】:

    • 那么,强调一下 OP 似乎想要的东西本质上是不可能的。
    • 在这种情况下,@NateEldredge 看起来就像nohup 命令完成了不可能的事情?
    • @SamVarshavchik nohup 通过与控制终端分离来阻止发送 SIGHUP 信号,它不会使进程忽略 SIGHUP 或 SIGQUIT 信号
    • 感谢您提供的信息丰富的回答。这对我作为计算机科学家的发展非常有见地和帮助。我能够修改代码以适应它。我会尽量更清楚地表达我的问题。我确实想要与nohup 类似的功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多