信号

一。信号概念

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("---------------------- "); } }

  

原文地址:https://www.cnblogs.com/sclu/p/11260462.html