sigpending函数

sigpending函数

sigpending函数返回一个被当前进程阻塞的信号集,这个信号集通过set参数返回。

#include <signal.h>

int sigpending(sigset_t *set);

Returns: 0 if OK, 1 on error

例子:

Figure 10.15. Example of signal sets and sigprocmask
#include "apue.h"

static void sig_quit(int);

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

    if (signal(SIGQUIT, sig_quit) == SIG_ERR)
        err_sys("can't catch SIGQUIT");

    /*
     * Block SIGQUIT and save current signal mask.
     */
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGQUIT);
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
        err_sys("SIG_BLOCK error");

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

    /*
     * Reset signal mask which unblocks SIGQUIT.
     */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
        err_sys("SIG_SETMASK error");
    printf("SIGQUIT unblocked\n");

    sleep(5);   /* SIGQUIT here will terminate with core file */
    exit(0);
}

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

Figure 10.15显示了很多我们描述过的信号功能。

进程阻塞了SIGQUIT信号,保存了当前的信号掩码(用于之后重置),然后休眠5秒钟。在进程运行期间发生的任何退出信号都会被阻塞,直到解除阻塞才会被传送。

注意,当我们阻塞了信号时保存了旧的信号掩码。解除阻塞时我们要对旧的掩作SIG_SETMASK操作。或者,我们也可以只对阻塞的信号做SIG_UNBLOCK操作。要知道如果我们写了一个函数,它能被其它函数调用,并且我们需要在我们的函数中阻塞一个信号,无论如何我们都不能通过SIG_UNBLOCK去解锁该信号。在这种情况下,我们必须使用SIG_SETMASK并且重置信号掩码到它之前的值,因为调用者可能在我们调用函数之前就已经阻塞了这个信号。稍后10.18节介绍system函数时会看到相关的例子。

如果在函数休眠阶段产生了退出信号,那么这个退出信号并不被阻塞,所以它会在sigprocmask返回之前被传递到进程。我们将会看到它发生,因为在信号处理函数中的printf会在sigprocmask后面的printf之前输出。

进程休眠5秒钟,用于干其它的事情。如果我们在休眠其间产生了退出信号,这个信号交会终止进程,因为当捕获该信号时,我们重置信号的动作为默认。看下面的输出,终端打印^\代表终端退出字符:

    $ ./a.out
    
    ^\                       generate signal once (before 5 seconds are up)
    SIGQUIT pending          after return from sleep
    caught SIGQUIT           in signal handler
    SIGQUIT unblocked        after return from sigprocmask
    ^\Quit(coredump)         generate signal again
    $ ./a.out
    
    ^\^\^\^\^\^\^\^\^\^\     generate signal 10 times (before 5 seconds are up)
    SIGQUIT pending
    caught SIGQUIT           signal is generated only once
    SIGQUIT unblocked
    ^\Quit(coredump)         generate signal again

发表回复