• 信号


    一。信号概念

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

      

  • 相关阅读:
    Linux 磁盘挂载和mount共享
    Socket编程实践(8) --Select-I/O复用
    JavaScript 作用域链图具体解释
    扩展MongoDB C# Driver的QueryBuilder
    Gray Code
    Android网络编程Socket【实例解析】
    设计模式之:代理模式
    LOL英雄联盟代打外挂程序-java实现
    MySQL系列:innodb源代码分析之线程并发同步机制
    linux压缩打包
  • 原文地址:https://www.cnblogs.com/sclu/p/11260462.html
Copyright © 2020-2023  润新知