天天看點

Linux程序間通信之信号通信

信号通信是Linux程序間通信的一種方式。

1.什麼是信号?

信号是系統響應某些條件而産生的一個事件,接收到該信号的程序會相應地采取一些措施。例如我們在windows系統中想強制結束一個程式我們需要用到的是任務管理器,而在Linux中,我們是通過信号來實作的,運作中的程序捕獲到信号并做出相應的行為。

信号的通信其實就是核心向使用者空間程序發送信号(隻有核心可以發送信号,使用者空間程序不可以)

核心中已經存在信号,不需要自己建立

Linux程式間通信之信号通信

2.信号的種類:

在Linux系統中共有64種信号。

通過kill -l 指令可以檢視。

Linux程式間通信之信号通信

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

Linux程式間通信之信号通信

在執行指令 kill 9 9890 後

程序被殺死

Linux程式間通信之信号通信

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;
}

           
Linux程式間通信之信号通信

與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;

           
Linux程式間通信之信号通信

繼續閱讀