信号通信是Linux程序間通信的一種方式。
1.什麼是信号?
信号是系統響應某些條件而産生的一個事件,接收到該信号的程序會相應地采取一些措施。例如我們在windows系統中想強制結束一個程式我們需要用到的是任務管理器,而在Linux中,我們是通過信号來實作的,運作中的程序捕獲到信号并做出相應的行為。
信号的通信其實就是核心向使用者空間程序發送信号(隻有核心可以發送信号,使用者空間程序不可以)
核心中已經存在信号,不需要自己建立
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX9QzValnVXl1asJTWwJ0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DM2QDNygTM2EzMyATM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
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;