美文网首页LinuxLinux学习之路
APUE读书笔记-10信号(8)

APUE读书笔记-10信号(8)

作者: QuietHeart | 来源:发表于2020-06-08 08:16 被阅读0次

13、sigpending函数

sigpending函数返回发送给进程的被阻塞的信号的集合以及处于提交给当前进程的信号的集合。通过函数的参数返回这个信号的集合。

#include <signal.h>
int sigpending(sigset_t *set);

函数如果成功返回0,失败返回1(其值实际为-1)。

举例:

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

    /*
     * 保存当前的signal mask并且阻塞信号SIGQUIT
     */
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGQUIT);
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
        err_sys("SIG_BLOCK error");

    sleep(5);   /* 这里,SIGQUIT会保持提交状态 */
    if (sigpending(&pendmask) < 0)
        err_sys("sigpending error");
    if (sigismember(&pendmask, SIGQUIT))
        printf("\nSIGQUIT pending\n");
    /*
     * 恢复原来的signal mask,以取消对SIGQUIT的阻塞
     */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
        err_sys("SIG_SETMASK error");
    printf("SIGQUIT unblocked\n");
    sleep(5);   /* 这里,SIGQUIT将会终止进程同时产生core文件*/
    exit(0);
}

例子给出了我们已经描述的所有的信号的特性。

进程阻塞SIGQUIT,保存它当前的signal mask,然后睡眠5秒。任何在这个期间发生的quit信号都会被阻塞,不会发送给进程直到这个信号取消阻塞。在5秒睡眠的最后,我们检查信号是否处于提交状态并且取消信号的阻塞。

注意,我们在阻塞信号之前,把原来的mask保存,在我们取消信号阻塞的时候,我们使用原来的mask做了一步SIG_SETMASK。当然,我们可能会使用SIG_UNBLOCK来取消我们已经阻塞的信号。但是,我们需要注意,如果我们写的函数可以被其他地方调用,并且如果我们需要在我们的函数中阻塞一个信号,我们不能使用SIG_UNBLOCK来取消对信号的阻塞。这里,我们需要使用SIG_SETMASK然后把信号恢复成它原来的值.这样做,是因为,那个调用我们函数的地方,可能在调用我们之前就特别地指定了要阻塞这个信号,所以我们不能仅仅简单地取消那个信号的阻塞。

如果我们在睡眠时发送了quit信号,而这个信号现在处于提交状态并且是取消阻塞的状态,那么它会在sigprocmask返回之前被发送给进程。我们将会看到这个现象的发生,因为处理函数中的printf输出,在sigprocmask调用接下来的printf输出之前。

进程然后再睡眠5秒,由于捕获信号之后,我们会把信号处理还原成默认,如果我们发送quit信号的时候是在睡眠的期间,信号就会把进程终止。

在下面的输出中,当我们输入[Ctrl]\的时候,终端会打印^\(终端退出字符):

$ ./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

消息"Quit(coredump)"是shell看到它的一个子进程非正常结束的时候,打印出来的。需要注意的是,当我们第二次运行程序的时候,我们在进程睡眠的时候发起quit信号10次,然而这个信号在它取消阻塞的时候只给进程发送了一次,这说明在这个系统上,信号没有被排队。

译者注

原文参考

参考: APUE2/ch10lev1sec13.html

相关文章

  • APUE读书笔记-10信号(8)

    13、sigpending函数 sigpending函数返回发送给进程的被阻塞的信号的集合以及处于提交给当前进程的...

  • APUE读书笔记-10信号(10)

    15、sigsetjmp和siglongjmp函数 前面,我们描述了setjmp和logjmp函数,这个函数可以用...

  • 信号函数编写研究

    APUE读书笔记 ToDoList [ ] sleep初级实现 2017年12月6日 10:41:30 [ ] ...

  • APUE读书笔记-10信号(13)

    19、sleep函数 我们在本文中的许多例子里都使用了sleep函数,并且我们在本章前面给出了两个有缺陷的slee...

  • APUE读书笔记-10信号(2)

    3、signal函数 UNIX系统中最简单的一个信号相关的接口就是signal函数。声明如下: 如果成功,这个函数...

  • APUE读书笔记-10信号(3)

    5、被中断的系统调用 早期Unix系统的一个特性是当一个进程被阻塞在一个很慢的系统调用的时候捕捉到一个信号,这时候...

  • APUE读书笔记-10信号(4)

    6、可重入函数 进程捕捉到信号时,进程正常执行的指令次序会被信号处理打断。进程会继续执行,但是这时候执行的是信号处...

  • APUE读书笔记-10信号(5)

    7、SIGCLD的含义 有两个很容易导致混淆的信号是SIGCLD和SIGCHLD。首先,SIGCLD是System...

  • APUE读书笔记-10信号(6)

    9、kill和raise函数 kill用来给一个进程或者一组进程发送信号,raise函数允许进程给它自己发送信号。...

  • APUE读书笔记-10信号(7)

    11、信号集合 我们需要一种数据类型来表示包含多个信号的信号集合,我们使用诸如sigprocmask这样的函数来告...

网友评论

    本文标题:APUE读书笔记-10信号(8)

    本文链接:https://www.haomeiwen.com/subject/kaioahtx.html