Linux進程間通信之信號通信

信號通信是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;

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章