linux之訊號產生

2021-07-30 12:48:01 字數 3570 閱讀 5547

使用者在終端按下某些鍵時,終端驅動程式會傳送訊號給前台程序,例如ctrl-c產生sigint信 號,ctrl-\產生sigquit訊號,ctrl-z產生sigtstp訊號。

sigint的預設處理動作是終止程序,

sigquit的預設處理動作是終止程序並且core dump,

首先解釋什麼是core dump(核心轉儲)。當乙個程序要異常終止時,可以選擇把程序的使用者空間記憶體資料全部儲存到磁碟上,檔名通常是core,這叫做core dump。

程序異常終止通常是因為有 bug,比如非法記憶體訪問導致段錯誤,事後可以用偵錯程式檢查core檔案以查清錯誤原因,這叫做 post-mortem debug(事後除錯)。乙個程序允許產生多大的core⽂檔案取決於程序的 resource limit(這個資訊儲存 在pcb中)。預設是不允許產⽣生core檔案的,因為core檔案中 可能包含使用者密碼等敏感資訊,不安全。

在開發除錯階段可以用ulimit命令改變這個限制, 允許產生core檔案。

首先用ulimit命令改變shell程序的resource limit,允許core檔案最大為1024k:

test.c源**:

#include 

int main()

因為ulimit命令改變了shell程序的resource limit, test程序的pcb由shell程序複製⽽而來,所以 也具有和shell程序相同的resource limit值,這樣就可以產生core檔案了。

進行除錯test:

這些條件由硬體檢測到並通知核心,然後核心向當前程序傳送適當的訊號。例如當前程序執行了除以0的指令,cpu的運算單元會產生異常,核心將這個異常解釋為 sigfpe訊號傳送給程序。再比如當前程序訪問了非法記憶體位址,,mmu會產生異常,核心 將 這個異常解釋為sigsegv訊號傳送給程序。

file.c 源**:

首先在後台執行死迴圈程式,然後⽤用kill命令給它發sigsegv訊號。

源**:

2829是test程序的id。之所以要再次回車才顯示segmentation fault,是因為在2829程序終止掉 之前已經回到了shell提示符等待使用者輸入下一條命令,shell不希望 segmentation fault資訊和用 戶的輸入交錯在一起,所以等使用者輸入命令之後才顯示。 指定某種訊號的kill命令可以有多種寫法,上面的命令還可以寫成kill -sigsegv 4568 或kill -11 4568, 11是訊號sigsegv的編號。以往遇 到的段錯誤都是由非法記憶體訪問產 生的,而這個程式本身沒錯,給它發sigsegv也能產生段錯誤。

kill命令是呼叫kill函式實現的。

kill函式可以給乙個指定的程序傳送指定的訊號。

raise函式可 以給當前程序傳送指定的訊號(自己給自己發訊號)。

#include 

int kill(pid_t pid, int signo);

int raise(int signo);

//這兩個函式都是成功返回0,錯誤返回-1。

源**:

#include 

#include

void handler(int data)

int main()

}

執行結果圖:

abort函式使當前程序接收到 訊號而異常終止。

#include 

void

abort(void);

//就像exit函式一樣,abort函式總是會成功的,所以沒有返回值。

執行結果圖:

pause()函式使該程序暫停讓出cpu

#include 

int pause(void);

源**:

#include 

#include

#include

#include

void sig_handler(int num)

int main()

exit(0);

}

執行結果圖:

可以看出程式每隔2秒就會收到訊號14,也就是sigalrm訊號;並且當處理完該訊號之後,直接執行pause()函式下面的語句;說明pause()是可被中斷的暫停;

alarm函式 和sigalrm訊號

#include 

unsigned

int alarm(unsigned

int seconds);

呼叫alarm函式可以設定乙個鬧鐘,也就是告訴核心在seconds秒之後給當前程序發 sigalrm訊號, 該訊號的預設處理動作是終止當前程序。這個函式的返回值是0或者是以前 設定的鬧鐘時間還餘下 的秒數。

源**:

#include 

int main()

}//這個程式的作用是1秒鐘之內不停地數數,1秒鐘到了就被sigalrm訊號終⽌止

執行結果圖:

源**:

#include 

#include

int count = 0;

void handler(int data)

int main()

return0;}

//這個函式遇上個函式作用相同,不同的是省去了i/o的輸出的切換。

可以看出,一秒鐘比上乙個**計數多了好多倍,說明有輸出的會延緩計數。

Linux 多執行緒應用 訊號產生,訊號處理

筆者有一種應用場景,a 執行緒從 socket 接收指令,根據指令在 b 執行緒進行相應工作。採用訊號機制,設定 sigusr1 的訊號處理函式 sighandler,a 執行緒解析指令後發射訊號 sigusr1,b 執行緒執行sighandler.因對 posix 訊號機制不熟,過程中產生了一些誤...

linux 產生各種訊號的原因

kill l 1 sighup 2 sigint 3 sigquit 4 sigill 5 sigtrap 6 sigabrt 7 sigbus 8 sigfpe 9 sigkill 10 sigusr1 11 sigse 12 sigusr2 13 sigpipe 14 sigalrm 15 si...

linux訊號共性 特質 產生訊號的方式以及概念

簡單 不能攜帶大量資訊 滿足條件才傳送。訊號是軟體層面上的 中斷 一旦訊號產生,無論程式執行到什麼位置,必須立即停止執行,處理訊號,處理結束,再繼續執行後續指令。每個程序收到的所有訊號,都是由核心負責傳送的,核心處理。產生訊號 1.按鍵產生,如 ctrl c ctrl z ctrl 2.系統呼叫產生...