关于信号函数处理过程中对信号的屏蔽理解。
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
备注,这个从网络上一个提问者,但是因为不好提评论而且没人回复的帖子说起。
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
相关文章推荐
- 使用python获得git中分支存成list
- java jar命令及补丁方法
- (php)session和cookie简单理解要点;
- GitPython git python 的开发库
- List 移除时要注意的问题
- iOS引导页不滑动N秒自动跳转的实现
- Python的高级Git库 Gittle
- 动态规划问题
- 解决 等分 布局
- N-Queen Problem
- poj2449 (第k条最短路)
- poj2449 (第k条最短路)
- Chapter 3-08
- Chapter 3-07
- Genymotion常见问题的解决方法
- LeetCode8:String to Integer (atoi)
- 网页刷新和重新输入网址的区别
- Chapter 2-InsertionSort
- Volley的post使用
- leetcode之Sliding Window Maximum