一。信号概念
1.1信号基本概念
1.2产生信号的5种方式
1.3信号的状态和处理方式
1.4信号的四要素
编号
名称
事件
默认处理动作(Term终止 Ign忽略 Core终止生成core文件 Stop暂停 Cont继续)
1.5kill函数
#include<stdio.h> #include<sys/types.h> #include<signal.h> #include<unistd.h> int main() { int ret=kill(getpid(),SIGKILL); if(ret==-1) { perror("kill err"); return 0; } return 0; }
1.6raise和abort
1.7alarm函数
1.8setitimer
it_interval表示下次定时的时间间隔,it_value表示定时的时常
tv_sec 表示秒 ,tv_usec表示毫秒
//第一次10.5s,之后每隔3s触发SIGALRM信号
//signal捕捉信号
//#include <signal.h>
//typedef void (*sighandler_t)(int);
//sighandler_t signal(int signum, sighandler_t handler);
#include<stdio.h> #include<unistd.h> #include<sys/time.h> #include<signal.h> void fun(int sign) { printf("SIGALRM TRIGGRED…… "); } int main() { signal(SIGALRM,fun); struct itimerval newtime; struct itimerval oldtime; //设置定时时常为10s 5000ms newtime.it_value.tv_sec=10; newtime.it_value.tv_usec=500; //下次时间隔0 newtime.it_interval.tv_sec=3; newtime.it_interval.tv_usec=0; int ret=setitimer(ITIMER_REAL,&newtime,&oldtime); if(ret==-1) { perror("setitimer err:"); return 0; } while(1); return 0; }
二。信号集操作
1.未决信号集和阻塞信号集
2.设定信号集的状态
3.sigprocmask函数
3.1 函数原型
3.1sigprocmask函数将自定义的信号集来设置阻塞信号集(根据SIG_BLOCK,SIG_UNBLOICK,SIG_SETMASK不同)
4.sigpending函数
5.打印未决信号集
#include<stdio.h> #include<unistd.h> #include<signal.h> void printped(sigset_t *ped) { int i; for(i=1;i<32;i++) { if(sigismember(ped,i)) { printf("1"); }else printf("0"); } printf(" "); } int main() { sigset_t myset,oldset,ped; //自定义信号集,保存改变前的阻塞信号集,保存未决信号集 sigemptyset(&myset); //初始化自定义信号集 sigaddset(&myset,SIGQUIT); //设置信号屏蔽 sigaddset(&myset,SIGINT); sigaddset(&myset,SIGTSTP); sigaddset(&myset,SIGKILL); //SIGKILL不能被设置为屏蔽 sigprocmask(SIG_BLOCK,&myset,&oldset); //通过自定义信号集和SIG_BLOCK设置阻塞 while(1) { sigpending(&ped); //传出未决信号集 printped(&ped); //打印 sleep(5); }
return 0;
}
三.信号捕捉
1.signal函数
sighandler_t 为返回值为void,参数为int的函数指针
2.sigaction函数
2.1函数原型
2.2 sigacntion捕捉信号代码
1 #include<stdio.h> 2 #include<signal.h> 3 #include<unistd.h> 4 void fun(int sign) 5 { 6 printf("%d signal is catched ",sign); 7 } 8 int main() 9 { 10 struct sigaction act,oldact; 11 act.sa_handler=fun; //设置信号捕捉函数 12 sigemptyset(&act.sa_mask); //初始化掩码 13 sigaddset(&act.sa_mask,SIGQUIT);//设置屏蔽信号 14 act.sa_flags=0; //默认属性,信号捕捉函数执行时。自动屏蔽本信号 15 int ret=sigaction(SIGINT,&act,&oldact); 16 if(ret==-1) 17 { perror("signaction err"); 18 return 0; 19 } 20 while(1); 21 }
2.3 信号捕捉特性(在信号捕捉函数执行时被屏蔽的信号,只执行一次)
四。SIGCHLD信号
1.SIGCHLD信号在子进程结束时发出,可以通过捕获SIGCHLD信号来回收子进程
2。代码示例
#include<stdio.h> #include<unistd.h> #include<sys/wait.h> #include<signal.h> #include<sys/types.h> void catch_sig(int num) { pid_t wpid; while((wpid=waitpid(-1,NULL,WNOHANG))>0) { printf("wait child %d sucess ",wpid); //每次接收信号回收所有能回收的子进程 } return ; } int main() { int i=0; pid_t pid; //在创建子进程之前屏蔽SIGHLD信号 sigset_t myset,oldset; sigemptyset(&myset); sigaddset(&myset,SIGCHLD); //oldsset保留现场,设置了SIGCHLD阻塞信号集 sigprocmask(SIG_BLOCK,&myset,&oldset); for(i =0;i<10;i++) { pid=fork(); if(pid == 0) { break; } } if(i==10){ sleep(20); //模拟注册信号晚于子进程结束 struct sigaction act; act.sa_flags=0; sigemptyset(&act.sa_mask); act.sa_handler = catch_sig; int ret=sigaction(SIGCHLD,&act,NULL); if(ret==-1) { perror("sigaction err"); return 0; } //解除屏蔽 sigprocmask(SIG_SETMASK,&oldset,NULL); while(1) { sleep(1); } }else if(i<10){ printf("I am %d child , pid= %d ",i,getpid()); // sleep(i); } }
六。pause函数
#include<stdio.h> #include<unistd.h> #include<signal.h> void catchSig(int sign) { printf("catch alarmw"); } int mysleep(unsigned int sec) { signal(SIGALRM,catchSig); alarm(sec); int ret=pause();
if(ret==-1&&errno==EINTR)
{
printf("pause sucess");
}
return 0; } int main() { while(1){ mysleep(1); printf("---------------------- "); } }