IPC--信号集-example

下面用刚学的几个函数做个实验。

example1

功能:每秒钟把各信号的未决状态打印一遍(阻塞了SIGINT信号,按Ctrl-C将会使SIGINT信号处于未决状态,按Ctrl-\仍可以终止程序)

step:

1) 调用函数sigprocmask可以读取或更改进程的阻塞信号集(又称信号屏蔽字)(目的是阻塞SIGINT信号);

2)调用sigpending读取当前进程的未决信号集,并将其打印。

程序如下:

IPC--信号集-example_第1张图片


程序运行时,每秒钟把各信号的未决状态打印一遍,由于我们阻塞了SIGINT信号,按Ctrl-C将会使SIGINT信号处于未决状态,按Ctrl-\仍然可以终止程序,因为SIGQUIT信号没有阻塞。

IPC--信号集-example_第2张图片


sigsuspend 函数

sigsuspend(const sigset_t *mask))用于等待接收某个信号,在接收到某个信号之前, 临时用mask替换进程的信号掩码, 并暂停进程执行,直到收到信号为止。sigsuspend 返回后将恢复调用之前的信号掩码。信号处理函数完成后,进程将继续执行。该系统调用始终返回-1,并将errno设置为EINTR。

注意:

sigsuspend的整个原子操作过程为:
(1) 设置新的mask阻塞当前进程 ;
(2) 收到信号,恢复原先mask;
(3) 调用该进程设置的信号处理函数 ;
(4) 待信号处理函数返回后,sigsuspend 返回。
 

实例:

功能描述:
sigsuspend 函数将进程的信号屏蔽字设置为 sigmask 指向的值。在捕捉到一个信号或发生了一个会终止该进程的信号之前,该进程被挂起。如果捕捉到一个信号而且从该信号处理程序返回,则sigsuspend返回,在返回之前,将进程的信号屏蔽字设置为调用sigsuspend之前的值。


用 法:
# include < signal . h>
int sigsuspend ( const sigset_t * sigmask) ;

参 数:
sigmask:  指向信号集的指针,里面设置了屏蔽的信号


返回说明:
函数没有成功返回值。如果它返回到调用者,则总是返回-1,并将 errno 设置为EINTR(表示一个被中断的系统调用)。

example2:

功能:测试sigsuspend函数

step:

1)注册SIGINT和SIGQUIT的信号处理函数

2)设置信号屏蔽字(阻塞SIGQUIT)

3)通过sigsuspend函数和SIGQUIT来结束程序

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <signal.h>  
  4. volatile sig_atomic_t quitflag; /* set nonzero by signal handler */  
  5.   
  6.  /* one signal handler for SIGINT and SIGQUIT */  
  7. static void sig_handler(int signo)  
  8. {  
  9.     if (signo == SIGINT)  
  10.                 printf("ninterruptn");  
  11.    else if (signo == SIGQUIT) 
  12.    {     
  13.            printf("recv signo = SIGQUIT\n");
  14.            quitflag = 1; /* set flag for main loop */ 
  15.    }


  16. int main(int argc, char *argv[])  
  17. {  
  18.         sigset_t newmask, oldmask, zeromask;  
  19.         if (signal(SIGINT, sig_handler) == SIG_ERR)  
  20.                 perror("signal(SIGINT) error");  
  21.         if (signal(SIGQUIT, sig_handler) == SIG_ERR)  
  22.                 perror("signal(SIGQUIT) error");  
  23.         sigemptyset(&newmask);  
  24.         sigemptyset(&zeromask);  
  25.         sigaddset(&newmask, SIGQUIT);  
  26.         /* Block SIGQUIT and save current signal mask */  
  27.         if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) != 0)  
  28.                 perror("sigprocmask SIG_BLOCK error");  
  29.         //while(1);   
  30.         while (quitflag == 0)  
  31.     {
  32.        printf(“start sigsuspend…\n”);
  33.                 sigsuspend(&zeromask);  
  34.        printf(“end sigsuspend…\n”);
  35.     }
  36.         quitflag = 0;  
  37.         /* Reset signal mask which unblocks SIGQUIT */  
  38.         if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)  
  39.                 perror("sigprocmask SIG_SETMASK error");  
  40.         exit(0);  
  41. }  

我们运行程序(注释while(1);版本):

输入: ctrl+c   :    输出 :  interrept

输入: ctrl+c   :    输出 :  interrept

输入: ctrl+c   :    输出 :  interrept

输入: ctrl+c   :    输出 :  interrept

输入: ctrl+\         程序终止

接着我们把程序中的while(1); 解除注释,运行程序

输入: ctrl+c   :    输出 :  interrept

输入: ctrl+c   :    输出 :  interrept

输入: ctrl+c   :    输出 :  interrept

输入: ctrl+c   :    输出 :  interrept

输入: ctrl+\         没有反应

分析:

程序停在while(1)的时候,这里屏蔽了sigquit的信号,而程序在sigsuspend阻塞时候,把屏蔽信号设置成zeromask,不阻塞任何信号,所以能接受到ctrl+\

你可能感兴趣的:(IPC--信号集-example)