进程间通信之sigaction_01<读书笔记>

 

                                                             

// 如果信号对应的信号处理运行时间过长,其他的信号可能在信号处理程序尚未返回前达到,这将导致新到达的信号中断现有的信号处理程序的执行,或者新到达的信号
被忽略(如果调用signal(SIG_IGN)话)。但很多时候程序员希望新到达的信号不被忽略,并且是在现有信号处理程序返回后被处理,而不是中断现有的信号处理程序运行  。
解决方案sigaction 代替signal

 

 

相关API
  //头文件: #include <signal.h>
     //函数原型:int sigaction(int signum, const struct sigaction *act, struct sigaction  *oldact);
  // 功能: 注册信号关联的信号处理程序(用于代替signal).并能修改(或者获取)与指定信号关联的信号处理程序的行为参数。
  //参数:
   signum - 捕获的信号 。不能捕获SIGSTOP 或SIGKILL
   act    - 用于指定信号处理程序的行为参数
   oldact - 用于保存信号处理程序的老行为参数。若不需要保存,则指定为NULL
 // 返回值:
    成功 返回 0  失败返回 -1
 // struct sigaction  结构体讲解
   //   - struct sigaction {
     void (*sa_handler)(int);  
      // 信号处理程序
     void (*sa_sigaction)(int , siginfo_t * , void *);
      // 指定信号处理程序。这个函数接收signum作为他的第一个参数,指向siginfo_t类型的指针作为第二个参数,
       指向ucontext_t 作为第三个参数
     sigset_t sa_mask; 
      //信号集合掩码 。该掩码中设置为1的位对应的信号将被屏蔽至信号处理程序结束后再被处理。默认情况下屏蔽同类信号
     int sa_flags;
      // 信号处理程序行为标志,其中较重要的有SA_SIGINFO 表示使用sa_sigaction代替sa_handler。SA_NODEFER表示不屏蔽同类信号
     void (*sa_restorer)(void);
      // 已废用
    };

 //信号处理程序行为标志
  // - SA_NOCLDSTOP 若signum 是SIGCHLD ,当一子进程停止时,不产生此信号
  // - SA_RESART  由此信号中断的系统调用自动重启
  // - SA_ONSTACK  若用sigaltstack 已说明了一替换栈,则此信号提送给替换栈上的进程
  // - SA_NOCLDWAIT 若signum 是SIGCHLD, 则当调用进程的子进程终止时,不创建僵尸进程。若调用进程在后面调用wait,则阻塞到他所有的子进程都终止,此时返回-1
  // - SA_NODEFER 当扑捉到此信号时,在执行其信号捕获函数时,系统不自动阻塞此信号
  // - SA_RESETHAND 对此信号的处理方式在此信号捕获函数的入口处恢复SIG_DFL
  // - SA_SIGINFO 选此项对信号处理程序提供附加信号

eg:
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
 #include <unistd.h>

 static void sig_int(int);

 int main(int argc ,char *argv[]){

   struct sigaction act;
   sigset_t newmask ,oldmask ,pendmask;

   if(signal(SIGQUIT , sig_int) == SIG_ERR){
     printf("can't catch SIGQUIT");
     exit(1);
   }
   if(signal(SIGINT , sig_int) == SIG_ERR){
     printf("can't catch SIGINT");
     exit(2);
   }
   sigemptyset(&act.sa_mask);
   sigaddset(&act.sa_mask , SIGQUIT);
   act.sa_handler = sig_int;
   act.sa_flags = 0 ;
   if(sigaction(SIGINT , &act , NULL) == -1){
     printf("can't catch SIGINT");
     exit(3);
   }

 /*      sigemptyset(&newmask);
   sigaddset(&newmask , SIGQUIT);

   if(sigprocmask(SIG_BLOCK , &newmask , &oldmask) < 0){
     printf("SIG_BLOCK ERROR");
     exit(4);
   }
 */
   sleep(15);
 /*      if(sigpending(&pendmask) < 0){
     printf("sigpending error");
     exit(5);
   }

   if(sigismember(&pendmask , SIGQUIT)){
     printf("\nSIGQUIT pending \n");
   }

   if(sigprocmask(SIG_SETMASK , &oldmask , NULL) < 0){
     printf("SIG_SETMASK error");
     exit(6);
   }
   printf("SIGQUIT unblocked \n");
 */
   sleep(100);

   return 0;
 }


 static void sig_int(int signo){
   int i ;
   if(signo == SIGINT){
     printf("received SIGINT \n");
     for(i = 1000000000 ; i > 0 ; i--)
       ;
       printf("processed SIGINT \n");

   }else if(signo == SIGQUIT){
     printf("caught SIGQUIT\n");
   }else{
     printf("received signal %d \n" , signo);
   }
   return ;
 }
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值