11.傳送訊號:raise;abort;kill/sigqueue||定時器alarm;setitimer
阿新 • • 發佈:2018-11-12
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