信号的发送
1、可靠信號與不可靠信號
可靠信號都是實時信號,不可靠信號都是非實時信號。實時信號都支持排隊,都是可靠信號。
不可靠信號的早期問題:1、UNIX進程每次處理信號后,將對信號響應設置為默認動作,而LINUX中再次發送不會重置默認動作,繼續是handler.
早期解決這個問題的方法是,在信號處理程序最后繼續調用signal(SIGINT,handler),重新安裝該信號;
void handler(int sig)//sig是signum
{
printf("recv a sig=%d\n",sig);
signal(SIGINT,handler);//還是有問題,在安裝時來信號了,還是執行默認程序。
}
2、早期UNIX下的不可靠信號主要是進程可能對信號做出錯誤反應導致信號丟失。處理SIGINT的handler還未返回時,又來了好幾個SIGINT,保留一個,后續
就丟棄了。不排隊。
3、Linux下調用完信號處理程序不必重新安裝信號處理函數。LINUX下的不可靠信號問題主要是第二方面信號可能丟失。
可靠信號(實時信號):原來定義的信號已有許多應用,不好改動,最終只好新加一些信號并且保證它們一開始就是可靠信號,支持排隊不會丟失,主要指
從SIGRTMIN--SIGRTMAX(33-64)之間的信號。
同時信號發送函數:sigqueue()支持排隊。信號安裝函數:sigaction()
非實時不支持排隊,前面的30幾個信號,不支持排隊,SIGHUP--SIGSYS,而且都是不可靠信號;
4、信號發送:
kill -9 pid //向pid 發送9號信號(SIGKILL)
int kill(pid_t pid,int sig)//
參數:
pid>0 sig信號發送給pid進程;
pid==0,sig信號將發送給調用者所在組中的每一個進程;
pid==-1,信號sig將被發送給調用者進程有權限發送的每一個進程(1號進程與自身除外);
pid<-1,信號將發給進程組=-pid中的每一個進程.
1 #include<unistd.h> 2 #include<sys/types.h> 3 #include<sys/stat.h> 4 #include<fcntl.h> 5 #include<stdlib.h> 6 #include<stdio.h> 7 #include<errno.h> 8 #include<string.h> 9 10 #include<signal.h> 11 #define ERR_EXIT(m)\ 12 do\ 13 {\ 14 perror(m);\ 15 exit(EXIT_FAILURE);\ 16 }while(0) //宏要求一條語句 17 void handler(int sig); 18 int main(int argc,char*argv[]) 19 { 20 21 if((signal(SIGUSR1,handler))==SIG_ERR) 22 ERR_EXIT("signal error");//fork之前安裝 23 pid_t pid=fork();//子進程繼承了信號安裝,在向進程組發送信號時,子進程也會調用handler信號處理程序進行處理 24 if(pid==-1) ERR_EXIT("fork error"); 25 if(pid==0){//子進程//kill(getppid(),SIGUSR1);//向父進程發送信號
26 /*pid=getpgrp();//獲取進程組ID 27 kill(-pid,SIGUSR1);//pid<-1,將向pid進程組中每個進程發送sig*/ 28 killpg(getpgrp(),SIGUSR1);//向進程組發送信號 29 exit(EXIT_SUCCESS);//子進程退出 30 } 31 //sleep(5);//父進程并未睡眠5秒,直接返回。因為sleep()函數會被被信號打斷。如果想sleep(5),可以如下操作: 32 int n=5; 33 do{ 34 n=sleep(n); //被信號打斷返回剩余的睡眠時間 35 }while(n>0); 36 return 0; 37 } 38 void handler(int sig)//sig是signum 39 { 40 printf("recv a sig=%d\n",sig); 41 }
?
下面是一些信號處理的一些函數:
int rasie(int sig)向調用者自身發送信號,等價于kill(getpid(),sig)
killpg(pgrp,sig) 向進程組發送信號,等價于kill(-pgrp,sig)
sigqueue 給進程發送信號,支持排隊
?
pause() 函數將進程置為可中斷睡眠狀態,讓出CPU時間片。然后它調用schedule()使得LINUX進程調度器找到另一個進程來運行。pause()使調用
者掛起,直到一個信號被捕獲時返回。
更多信號發送函數:alarm函數,setitimer函數,abort函數
alarm只能發送 SIGALRM信號(用于時鐘信號)
或者手工發送SIGALRM信號: kill? -SIGALRM? `ps aux | grep 01alarm | grep -v? vim | grep -v grep | awk '{print $2}' `
unsigned int alarm(unsigned int seconds) 過了seconds后會產生SIGALRM信號
?
轉載于:https://www.cnblogs.com/wsw-seu/p/8366457.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
- 上一篇: day_work_02
- 下一篇: 设计模式导图