11.发送信号:raise;abort;kill/sigqueue||定时器alarm;setitimer

1.[发送信号]函数相关:raise;abort;kill/sigqueue

1.raise--自己给自己发信号:int raise(int sig);
	等价于:kill(getpid(),int sig);
2.abort--给自己发送异常终止信号SIGABRT
	在哪个进程中调用abort函数,哪个进程就会终止,并发送SIGABRT信号
----------------------------------------------------------
3.kill--发送信号给指定进程:int kill(pid_t pid, int sig);
	pid>0:发信号给指定的进程
	pid=0:调用kill函数的进程的(同一组的所有进程)
	pid<-1:取|pid|发给对应进程组
	pid=-1:发送给进程有权限发送的系统中所有进程
	
4.sigqueue  发送信号(发送信号的同时,将数据也发送给[信号处理函数])
int sigqueue(pid_t pid, int sig, const union sigval value);
1.函数功能:
	与kill函数功能几乎一样,都是发送信号
    与kill函数不同点是:sigqueue函数发送信号的时候,将数据也发送给[信号处理函数]
2.sigqueue的第三个参数:union sigval value 携带数据
		   union sigval {
               int   sival_int;
               void *sival_ptr;
           };
3.sigqueue的使用规则:***
	[1]使用sigqueue函数发送数据给信号处理函数;
	[2]注册信号处理函数必须使用sigaction
		int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
详细过程:
	[1]定义sigaction的信号处理函数:其中, siginfo_t*  s_t参数用来接收sigqueue函数发来的数据
	  void handler(int signum, siginfo_t* s_t, void* ptr){                                                                           
	    printf("         param = %d\n",s_t->si_int);                                                                             
	  }   	
	[2]定义并初始化sigaction的第二个参数变量:struct sigaction类型的变量
	    struct sigaction act;                                                                                                        
	    sigemptyset(&act.sa_mask);    //清空阻塞集合                                                                                               
	    act.sa_flags=SA_SIGINFO;                                                                                                     
	    act.sa_sigaction=handler; //回调函数  
	[3]调用sigaction函数注册XXX信号:sigaction(XXX,&act,NULL); 	
	[4]给指定进程,通过sigqueue函数发送[带有数据的XXX信号]
		union sigval value;
		value.sival_int=24;
		sigqueue(getppid(),XXX,value);

2.alarm 实现一次性定时

unsigned int alarm(unsigned int seconds);
[1]执行效果:
	程序等待seconds秒后,定时器被触发一次
[2]SIGALARM信号的默认处理方式:终止进程
[3]重点:多次调用alarm函数
	1.如果在seconds秒内再次调用了alarm函数设置了新的闹钟,则后面定时器的设置将覆盖前面的设置,
即之前设置的秒数被新的闹钟时间取代;
	2.当参数seconds为0时,之前设置的定时器闹钟将被取消,并将剩下的时间返回。
[4]程序案例:
	int main(){                                                                                                                      
	  int ret=alarm(2);                                                                                                              
	  printf("ret = %d\n",ret);                                                                                                                                                                                                              
	  sleep(10);                                                                                                                     
	  printf("--------------"); //此句话不会被打印
	}  
	[gjw@localhost 4-signal]$ ./alarm 
	ret = 0
	闹钟
分析:因为alarm(2)时间到时,产生SIGALRM信号,默认处理:直接杀死进程

3.setitimer 实现周期性定时

int setitimer(int which, 
	const struct itimerval *restrict value,
	struct itimerval *restrict ovalue  //设为NULL
);
[1]执行效果:
	程序执行restrict value.it_value时间后,第一次触发定时器
	之后每间隔restrict value.it_interval时间,周期性地触发定时器
[2]参数:
	which
		ITIMER_REAL 自然定时法  (real=用户+内核+损耗)SIGALRM
		ITIMER_VIRTUAL 只计算[用户]时间  SIGVTALRM
		ITIMER_PROF  只计算[用户+内核]时间  SIGPROF  
	restrict value
		struct itimerval {
		    struct timeval it_interval;   //定时器周期性触发的时间
		    struct timeval it_value;  //定时器第一次触发的时间
		};
		struct timeval { //二者是相加的关系
		    time_t      tv_sec; //秒
		    suseconds_t tv_usec;  //微秒
		};
[3]程序案例:
  void handler(){                                                                                                                
    printf("__________________\n");                                                                                              
  }                                                                                                                              
                                                                                                                                 
  int main(){                                                                                                                    
    signal(SIGALRM,handler);                                                                                                                                                                                                                                   
    struct itimerval new_val;                                                                                                    
    //从当前时刻开始,定时器第一次触发的时间                                                                                                                           
    new_val.it_value.tv_sec=6;                                                                                                   
    new_val.it_value.tv_usec=0;                                                                                                  
	//定时器周期性触发的时间
    new_val.it_interval.tv_sec=2;                                                                                                
    new_val.it_interval.tv_usec=0;                                                                                               
    setitimer(ITIMER_REAL,&new_val,NULL);                                                                                        
                                                                                                                                 
    while(1){                                                                                                                    
      printf("hello,world\n");                                                                                                   
      sleep(1);                                                                                                                  
    }                                                                                                                            
  }   
  [gjw@localhost 4-signal]$ ./alarm 
hello,world
hello,world
hello,world
hello,world
hello,world
hello,world
__________________
hello,world
hello,world
__________________
hello,world
hello,world
__________________
hello,world

猜你喜欢

转载自blog.csdn.net/weixin_36750623/article/details/83061309
今日推荐