您的位置:首页 > 其它

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

2015-10-23 00:38 344 查看
首先看下面的例子。

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

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的处理函数,处理完毕后,才出来。

#include "apue.h"
static void sigparse1(int sig,siginfo_t * param,void * p2){
pr_mask("in sigparse1: ");
//raise(SIGUSR2);
sleep(5);
printf("end sigparse1\n");
}

static void sigparse2(int sig,siginfo_t * param,void *p2){
pr_mask("in sigparse2: ");
//raise(SIGUSR1);
sleep(5);
printf("end sigparse2\n");
}

int main (int argc, const char * argv[]) {
struct sigaction act;
act.sa_sigaction=sigparse1;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGUSR2);
sigaction(SIGUSR1, &act, NULL);

act.sa_sigaction = sigparse2;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
//sigaddset(&act.sa_mask,SIGUSR1);
sigaction(SIGUSR2, &act, NULL);

printf("start working ,send signal cmd:\nkill -s USR1 %d\n",getpid());
//raise(SIGUSR1);
//sleep(1);
//raise(SIGUSR2);
pause();
sleep(25);
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: