关于信号函数处理过程中对信号的屏蔽理解。

来源:互联网 发布:罗盘软件 编辑:程序博客网 时间:2024/04/30 13:16

首先看下面的例子。

备注,这个从网络上一个提问者,但是因为不好提评论而且没人回复的帖子说起。


2,编译运行后 另外起一个终端,
   kill -s USR2 842
   kill -s USR1 842
输出:
   start working ,send signal cmd:
   kill -s USR1 842
   in sigparse2: SIGUSR2
   in sigparse1: SIGUSR1 SIGUSR2
   end sigparse1
   end sigparse2

而如果这样:
   kill -s USR1 854
   kill -s USR2 854
输出:
   start working ,send signal cmd:
   kill -s USR1 854
   in sigparse1: SIGUSR1 SIGUSR2
   end sigparse1
   in sigparse2: SIGUSR2
   end sigparse2


区别在于先执行kill USR2的回调的时候,信号1来了。SLEEP被唤醒(进入调度,但是没有从SLEEP出来),马上进入信号2的处理函数,处理完毕后,才出来。





  1. #include "apue.h"  
  2. static void sigparse1(int sig,siginfo_t * param,void * p2){  
  3.         pr_mask("in sigparse1: ");  
  4.                 //raise(SIGUSR2);  
  5.         sleep(5);  
  6.         printf("end sigparse1\n");  
  7. }  
  8.   
  9. static void sigparse2(int sig,siginfo_t * param,void *p2){  
  10.         pr_mask("in sigparse2: ");  
  11.                 //raise(SIGUSR1);  
  12.         sleep(5);  
  13.         printf("end sigparse2\n");  
  14. }  
  15.   
  16. int main (int argc, const char * argv[]) {  
  17.         struct sigaction act;  
  18.         act.sa_sigaction=sigparse1;  
  19.         act.sa_flags = 0;  
  20.         sigemptyset(&act.sa_mask);  
  21.         sigaddset(&act.sa_mask, SIGUSR2);  
  22.         sigaction(SIGUSR1, &act, NULL);  
  23.           
  24.           
  25.         act.sa_sigaction = sigparse2;  
  26.         act.sa_flags = 0;  
  27.         sigemptyset(&act.sa_mask);  
  28.                 //sigaddset(&act.sa_mask,SIGUSR1);  
  29.         sigaction(SIGUSR2, &act, NULL);  
  30.           
  31.         printf("start working ,send signal cmd:\nkill -s USR1 %d\n",getpid());  
  32.                 //raise(SIGUSR1);  
  33.                 //sleep(1);  
  34.                 //raise(SIGUSR2);  
  35.         pause();  
  36.         sleep(25);  
  37.         return 0;  





附2:

SA_NODEFER的作用。

就是不屏蔽自己。不设置的话为屏蔽自己,即使MASK没有设置。有点递归中断的感觉吧。哈哈

#include <signal.h>
#include <unistd.h>

static void catch_signal(int);

static void catch_alarm(int signo)
{

printf("alarm 1s\n");

}



int main(int argc, char* argv[])
{
struct sigaction act;
struct itimerval value;
act.sa_handler = catch_signal; //设置信号处理函数
  act.sa_flags = SA_NODEFER; //设置信号处理标志位
  sigemptyset(&act.sa_mask); //清空信号集,信号函数执行过程不屏蔽本身信号 ==1==
  sigaction(SIGRTMIN+1,&act,NULL); //捕获定时信号


  //signal(SIGALRM,catch_alarm);

  //设置一个定时器,1s发送一个定时信号
  value.it_value.tv_sec=1;
  value.it_value.tv_usec=0;
  value.it_interval.tv_sec = 1;
  value.it_interval.tv_usec = 0;
//  if(setitimer(ITIMER_REAL,&value,NULL)<0){
//perror("setitimer");
//  }

while(1){
        printf("pause start\n");
  pause(); //让进程暂停直到信号的出现
        printf("pause over!\n");

}
return 0;
}

//所有信号处理函数
static void catch_signal(int signo)
{
int i;
 switch(act->sa_flags)
    {
        case SIG_DFL:
        printf("Default action\n");
        break;
        case SIG_IGN:
        printf("Ignore the signal\n");
        break;
        default:
        printf("0x%x\n", act->sa_handler);
    }
printf("SIGNO %d \n",signo);
i=sleep(20); //用于测试函数执行过程是否会屏蔽本身信号,如果1s输出一次说明未屏蔽
  //如果5s输出一次说明已屏蔽
printf("SIGALAM---%d\n",i);
 return;
}、

连续按 kill -35 3150; 6次。

SIGNO 35
SIGNO 35
SIGNO 35
SIGNO 35
SIGNO 35
SIGNO 35 
SIGALAM---0
SIGALAM---19
SIGALAM---19
SIGALAM---19
SIGALAM---19
SIGALAM---18
pause over!
pause star







0 0