信号--sigpending函数

信号--sigpending函数

sigpending函数返回被阻塞而为调用进程待定的信号。信号集通过set参数返回。



  1. #include <signal.h>

  2. int sigpending(sigset_t *set);

  3. 成功返回0,错误返回-1


下面的代码展示了我们描述过的所有信号的特性。



  1. #include <signal.h>

  2. static void sig_quit(int);

  3. int
  4. main(void)
  5. {
  6.     sigset_t newmask, oldmask, pendmask;

  7.     if (signal(SIGQUIT, sig_quit) == SIG_ERR) {
  8.         printf("can't catch SIGQUIT");
  9.         exit(1);
  10.     }

  11.     /*
  12.      * Block SIGQUIT and save current signal mask.
  13.      */
  14.     sigemptyset(&newmask);
  15.     sigaddset(&newmask, SIGQUIT);
  16.     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
  17.         printf("SIG_BLOCK error\n");
  18.         exit(1);
  19.     }

  20.     sleep(5); /* SIGQUIT here will remain pending */
  21.     if (sigpending(&pendmask) < 0) {
  22.         printf("sigpending error\n");
  23.         exit(1);
  24.     }
  25.     if (sigismember(&pendmask, SIGQUIT))
  26.         printf("\nSIGQUIT pending\n");

  27.     /*
  28.      * Reset signal mask which unblocks SIGQUIT.
  29.      */
  30.     if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
  31.         printf("SIG_SETMASK error\n");
  32.         exit(1);
  33.     }
  34.     printf("SIGQUIT unblocked\n");

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

  38. static void
  39. sig_quit(int signo)
  40. {
  41.     printf("caught SIGQUIT\n");
  42.     if (signal(SIGQUIT, SIG_DFL) == SIG_ERR) {
  43.         printf("can't reset SIGQUIT\n");
  44.         exit(1);
  45.     }
  46. }

进程阻塞了SIGQUIT,保存它当前的信号掩码(以便稍后重置),然后睡眠5秒。在此期间的任何退出信号的发生都不会被分发,直到信号被反阻塞。在5秒的睡眠后,我们检查信号是否待定并反阻塞这个信号。

注 意我们在阻塞信号前保存了老的掩码。为了反阻塞信号,我们执行了老掩码的SIG_SETMASK。另一种方式,我们可以只SIG_UNBLOCK我们已经 阻塞的信号。然而,要知道如果我们写了一个可以被其他调用的函数,且我们需要在我们的函数里阻塞一个信号,那么我们不能使用SIG_UNBLOCK来反阻 塞这个信号。在这种情况下,我们必须使用SIG_SETMASK并把信号掩码重置为它之前的值,因为调用者在调用我们的函数前可能已经阻塞了这个信号。我 们将在10.18节里的system函数里看到一个这样的例子。


如果我们在睡眠期产生退出信号,那么信号现在是待定而无阻塞的,所以它在sigprocmask返回值被分发。我们将看到这个发生因为信号处理器里的printf在sigprocmask调用后面的printf之前输出。


进程然后又睡了5秒。如果我们在这个睡眠期间产生了退出信号,那么信号应该终止这个进程,因为我们在捕获到它后把这个信号重置到默认值。在下面的输出里,当我们输入终端退出符Control-backslash时终端打印出^\:

$ ./a.out
^\
SIGQUIT pending
caught SIGQUIT
SIGQUIT unblocked
$ ./a.out
^\^\^\^\^\^\^\^\^\^\
SIGQUIT pending
caught SIGQUIT
SIGQUIT unblocked


注意第二次运行程序时我们在进程睡眠时产生了十倍的退出信号,但是信号在被反阻塞后只被分发给了进程一次。这证明了信号没有在这个系统上排队。

你可能感兴趣的:(虚拟化)