【问题标题】:About sigprocmask(), SIG_BLOCK and SIG_SETMASK关于 sigprocmask()、SIG_BLOCK 和 SIG_SETMASK
【发布时间】:2016-12-27 12:38:10
【问题描述】:

在第 10 章 APUE 的信号中。

我有一些关于sigprocmask()SIG_BLOCKSIG_SETMASK 的问题。

  1. 书上说“我们在屏蔽信号时保存了旧面罩”。我的理解是:

我们声明一个sigset_t类型的newmask,然后sigempty(&newmask)表示初始化新掩码以便排除newmask指向的所有信号,最后将SIGQUIT添加到newmask集合中。

但我不确定以下是什么意思。是SIG_BLOCKnewmasksigprocmask()指向的信号指向oldmask吗?

sigprocmask(SIG_BLOCK, &newmask, &oldmask)

  1. “为了解除对信号的阻塞,我们对旧掩码进行了SIG_SETMASK

oldmask 是一个包含SIGQUITsigset_t,如何解除对信号的阻塞(SIGQUIT)?

sigprocmask(SIG_SETMASK, &oldmask, NULL)

这是完整的代码:

#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>

static void sig_quit(int signo) {
    printf("caught SIGQUIT\n");
    if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)
        printf("can't reset SIGQUIT\n");
}

int main() {
    sigset_t newmask, oldmask, pendmask;

    if (signal(SIGQUIT, sig_quit) == SIG_ERR)
        printf("can't catch SIGQUIT\n");

    /* Block SIGQUIT and save current signal mask. */
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGQUIT);

    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
       printf("SIG_BLOCK error");
    sleep(5);   /* SIGQUIT here will remain pending */
    if (sigpending(&pendmask) < 0)
       printf("sigpending error");
    if (sigismember(&pendmask, SIGQUIT))
       printf("\nSIGQUIT pending\n");

    /* Restore signal mask which unblocks SIGQUIT. */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
       printf("SIG_SETMASK error");
    printf("SIGQUIT unblocked\n");
    sleep(5);   /* SIGQUIT here will terminate with core file */

    return 0;
}

非常感谢!

【问题讨论】:

    标签: c unix signals


    【解决方案1】:

    我们声明一个sigset_t类型的newmask,然后sigempty(&newmask)表示初始化newmask,排除newmask指向的所有信号,最后将SIGQUIT加入newmask集合。

    不完全是。 sigemptyset() 排除了 所有来自 newmask 的信号(即它是一个 信号集)。

    但我不确定以下是什么意思。是否将newmask和sigprocmask()指向的信号SIG_BLOCK指向oldmask?

    sigprocmask(SIG_BLOCK, &amp;newmask, &amp;oldmask) 使用newmask 设置新的信号掩码(即如果成功,则仅阻止SIGQUIT)并在oldmask 中返回 信号掩码。

    oldmask是一个包含SIGQUIT的sigset_t,如何解除对信号(SIGQUIT)的阻塞?

    那不是真的。 old 信号掩码是SIGQUIT 被阻止之前 的信号掩码,当您阻止SIGQUIT 时由sigprocmask() 返回并存储在oldmask 中。因此,sigprocmask(SIG_SETMASK, &amp;oldmask, NULL) 恢复了旧的信号掩码(无论信号掩码之前调用sigprocmask(SIG_BLOCK, &amp;newmask, &amp;oldmask))。

    【讨论】:

    • 至于sigprocmask(SIG_BLOCK, &amp;newmask, &amp;oldmask),前两个参数做一件事,最后一个参数做另一件事(即,只保存原始设置)?它是否正确?所以这就是为什么我们需要在代码中使用pendmask(我们也可以使用newmask吗?)
    • "[...]这是正确的吗?"是的。 pendmask 是存储信号 pending 的列表(当它们被阻塞时)。您可以重新使用newmask,因为在成功调用sigprocmask() 后,通过清空它就不需要它了。但为了清楚起见,最好使用不同的变量。
    猜你喜欢
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    • 2011-02-24
    • 2021-09-10
    • 2016-02-08
    • 2011-01-11
    • 2018-10-16
    • 2014-06-09
    相关资源
    最近更新 更多