信號通信是Linux進程間通信的一種方式。
1.什麼是信號?
信號是系統響應某些條件而產生的一個事件,接收到該信號的進程會相應地採取一些措施。例如我們在windows系統中想強制結束一個程序我們需要用到的是任務管理器,而在Linux中,我們是通過信號來實現的,運行中的進程捕獲到信號並做出相應的行爲。
信號的通信其實就是內核向用戶空間進程發送信號(只有內核可以發送信號,用戶空間進程不可以)
內核中已經存在信號,不需要自己創建
2.信號的種類:
在Linux系統中共有64種信號。
通過kill -l 命令可以查看。
3.信號通信的框架:
(1)信號的發送:kill ,raise ,alarm
(2)信號的接收:pause ,sleep ,while(1)
(3)信號的處理:signal
(1)信號的發送:
kill 函數:發送信號給任意進程
函數名 | kill |
---|---|
頭文件 | #include <signal.h> ,#include<sys/types.h> |
函數原型 | int kill (pid_t pid,int sig) |
參數 | pid ----- 1.正數:要接收信號的進程的進程號。 |
2. 0:信號被髮送到所有和pid 進程在同一個進程組的進程 | |
3. -1 :信號被髮送給所有在進程表中的進程(除了進程號最大的進程除外) | |
sig :信號的種類 | |
函數返回值 | 成功:0 ,出錯:-1 |
舉個栗子:
在當前目錄下運行一個死循環進程./a.out
在執行指令 kill 9 9890 後
進程被殺死
raise函數:發送信號給自己
函數名 | raise |
---|---|
頭文件 | #include <signal.h> ,#include <sys/types.h> |
函數原型 | int raise(int sig) |
參數 | sig : 信號的種類 |
返回值 | 成功:0,錯誤:-1 |
alarm 函數:鬧鐘信號發送函數,接受到信號後默認處理終止程序。
函數名 | alarm |
---|---|
頭文件 | #include <unistd.h> |
函數原型 | unsigned int alarm(unsigned int seconds) |
參數 | seconds:指定的秒數 |
返回值 | 成功:若之前已經調用過alarm函數且未結束,返回上一個鬧鐘的時間,否則0。錯誤:-1 |
舉個栗子:
int main(){
int i;
printf("alarm have ready\n");
alarm (5);
printf("alarm have send\n");
for(i = 0;i < 9;i++){
sleep(1);
printf("i = %d\n",i);
}
return 0;
}
與raise 函數比較:
相同點:通過內核發送信號到當前進程
不同點:alarm只會發送SIGALARM信號,且延時一定的時間,raise函數則立即發送
(2)信號的接收:
pause 函數:
函數名 | pause |
---|---|
頭文件 | #include <unistd.h> |
函數原型 | int pasue(void) |
返回值 | 成功:0。錯誤:-1 |
pause函數會使進程處於睡眠狀態(S)
sleep 函數
while(1)
(3)信號的處理:signal
當進程收到信號後:
1.進程的默認處理方式:A.忽略 B.終止進程 C.暫停(內核爲用戶設置的默認處理方式)
2.自己的處理方式:signal 函數
將自己的處理方式告訴內核,當收到信號後,採用自己的處理方式
函數名 | signal |
---|---|
頭文件 | #include <signal.h> |
函數原型 | void (*signal (int signum,void(handler)(int)))(int) |
參數 | signum:指定信號 |
handler:1.SIG _IGN:忽略該信號 | |
2.SIG _DFL:採用系統默認的處理方式 | |
3.SIG _DFL:自定義信號處理指針 | |
返回值 | 成功:之前設置的信號處理方式。錯誤:-1 |
signal 函數有兩個參數:
第一個參數是整型變量(信號值)
第二個參數是一個函數指針,是我們自己寫的處理函數,該函數返回值是一個函數指針
有幾個signal函數就按最新的函數處理
舉個栗子:
void myfun(int signum){
int i;
for(i = 0;i<4;i++){
sleep(1);
printf("in myfun \n");
}
return ;
}
int main(){
int i;
signal(14,myfun); //定義信號的自己處理方式
alarm (5);
printf("alarm have send\n");
for(i = 0;i < 9;i++){
sleep(1);
printf("i = %d\n",i);
}
return 0;