《unix高级环境编程》信号——sigsuspend 函数

来源:互联网 发布:人机界面数据记录 编辑:程序博客网 时间:2024/05/18 08:23

sigsuspend 函数

       更改进程的信号屏蔽字可以阻塞所选择的信号,或解除对它们的阻塞,使用这种技术可以保护不希望由信号中断的代码临界区。如果希望对一个信号解除阻塞,然后pause 等待以前被阻塞的信号发生,就是把“解除信号屏蔽”和“挂起等待信号”这两步能合并成一个原子操作。sigsuspend 函数能够实现该功能,即包含了pause的挂起等待功能,同时临时解除对某个信号的屏蔽。以下是该函数的原型:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include <signal.h>  
  2. int sigsuspend(const sigset_t *sigmask);//返回值:-1,并将errno设置为EINTR;  

        跟 pause 一样,sigsuspend 没有成功返回值,只有执行了一个信号处理函数之后sigsuspend 才返回,返回值为-1,并将errno 设置为 EINTR。调用sigsuspend 时,进程的信号屏蔽字由sigmask 参数指定,可以通过指定sigmask 来临时解除对某个信号的屏蔽,然后挂起等待,当sigsuspend 返回时,进程的信号屏蔽字恢复为原来的值。

测试程序:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include <signal.h>  
  2. /* 
  3. int sigsuspend(const sigset_t *sigmask);//返回值:-1,并将errno设置为EINTR; 
  4. */  
  5. #include "apue.h"  
  6. #include "pr_mask.h"  
  7.   
  8. static void sig_func(int signo);  
  9.   
  10. int main(void)  
  11. {  
  12.     sigset_t newmask, oldmask, waitmask;  
  13.   
  14.     pr_mask("Program start: ");  
  15.   
  16.     if(signal(SIGINT,sig_func) == SIG_ERR)  
  17.         err_sys("signal error");  
  18.     sigemptyset(&newmask);//初始化信号集  
  19.     sigaddset(&newmask,SIGINT);//添加SIGINT信号  
  20.   
  21.     sigemptyset(&waitmask);  
  22.     sigaddset(&waitmask,SIGUSR1);  
  23.   
  24.     //屏蔽信号  
  25.     /* 
  26.      * Block SIGINT and save current signal mask 
  27.      */  
  28.     if(sigprocmask(SIG_BLOCK,&newmask,&oldmask) < 0)  
  29.         err_sys("SIG_BLOCK error");  
  30.   
  31.     pr_mask("in critical region: ");  
  32.   
  33.     //临时修改进程信号屏蔽字,在捕捉信号之前,将进程挂起等待  
  34.     /* 
  35.      * pause, allowing all of signals except SIGUSR1 
  36.      */  
  37.     if(sigsuspend(&waitmask) != -1)  
  38.         err_sys("sigsuspend error");  
  39.     pr_mask("after return from sigsuspend: ");  
  40.     /* 
  41.      * reset signal mask which unblocks SIGINT 
  42.      */  
  43.     if(sigprocmask(SIG_SETMASK,&oldmask,NULL) < 0)  
  44.         err_sys("SIG_SETMASK error");  
  45.   
  46.     pr_mask("program exit: ");  
  47.   
  48.     exit(0);  
  49. }  
  50.   
  51. static void sig_func(int signo)  
  52. {  
  53.     pr_mask("\nin sig_func: ");  
  54. }  
输出结果:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. $ ./sigsuspend  
  2. Program start:   
  3. in critical region: SIGINT    
  4. ^C  
  5. in sig_func: SIGINT SIGUSR1   
  6. after return from sigsuspend: SIGINT      
  7. program exit:  

  1. 首先设置信号 SIGINT为信号屏蔽字进行阻塞;
  2. 当程序执行了 sigsuspend 后,临时使 SIGUSR1 成为信号屏蔽字进行阻塞,对 SIGINT 解除阻塞,并且挂起进程,等待信号输入;
  3. 我们在终端中输入ctrl-C ,即输入一个中断信号,进程捕捉到中断信号,调用捕捉函数sig_func 进行处理,处理完中断信号后sigsuspend 函数返回-1。此时,进程的信号屏蔽字恢复为原来的值SIGINT
0 0
原创粉丝点击