1. 程式人生 > >11.傳送訊號:raise;abort;kill/sigqueue||定時器alarm;setitimer

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("--------------"); //此句話不會被列印
	}  
	[
[email protected]
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);                                                                                                                  
    }                                                                                                                            
  }   
  [
[email protected]
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