基本概念
信号是事件發生時對程序的通知機制,也就是所謂的軟體中斷。信号和硬體的中斷類似,是軟體層對中斷機制的模拟,在多數情況下是無法預測信号産生的時間,是以軟體層提供了一種處理異步事件的方法。
信号的來源分為硬體來源和軟體來源。
硬體來源:
硬體發生異常,即硬體檢測到錯誤條件并通知核心,随即再由核心發送相應的信号給相關程序,如除數為0、無效的記憶體引用等。
使用者按終端鍵,引起終端産生的信号(比如Ctrl + C鍵産生SIGINT)。
軟體來源:
使用者通過指令殺死,如kill指令。
發生軟體事件, 如程式執行raise, alarm、setitimer、sigqueue等函數。
信号通常是發送給對應的程序,當信号到達後,該程序需要做出相應的處理措施,通常程序會視具體信号執行相應的操作,有三種操作方式。
忽略信号:
信号到達後、直接忽略,就好像是沒有出該信号,信号對該程序不會産生任何影響。事實上,大多數信号都可以使用這種方式進行處理,但有兩種信号卻決不能被忽略,分别是SIGKILL 和 SIGSTOP。
捕獲信号:
當信号到達程序後,執行signal()綁定好的信号處理函數。
執行系統預設操作:
程序不對該信号事件作出處理,而是交由系統進行處理,每一種信号都會有其對應的系統預設的處理方式。
在linux系統中通過<code>kill -l</code>指令可以檢視到相應的信号。信号編号是從 1 開始,不存在編号為 0 的信号,事實上 kill()函數對信号編号 0 有着特殊的應用。

注意:括号" ) "前面的數字對應該信号的編号,編号 1~31 所對應的是不可靠信号,編号 34~64 對應的是可靠信号,從圖中可知,可靠信号并沒有一個具體對應的名字,而是使用了 SIGRTMIN+N 或 SIGRTMAXN 的方式來表示。其中32和33空缺。
不可靠信号表
<col>
值
名稱
解釋
預設動作
1
SIGHUP
挂起
2
SIGINT
中斷
3
SIGQUIT
退出
4
SIGILL
非法指令
5
SIGTRAP
斷點或陷阱指令
6
SIGABRT
abort發出的信号
7
SIGBUS
非法記憶體通路
8
SIGFPE
浮點異常
9
SIGKILL
kill信号
不能被忽略、處理和阻塞
10
SIGUSR1
使用者信号1
11
SIGSEGV
無效記憶體通路
12
SIGUSR2
使用者信号2
13
SIGPIPE
管道破損,沒有讀端的管道寫資料
14
SIGALRM
alarm發出的信号
15
SIGTERM
終止信号
16
SIGSTKFLT
棧溢出
17
SIGCHLD
子程序退出
預設忽略
18
SIGCONT
程序繼續
19
SIGSTOP
程序停止
20
SIGTSTP
21
SIGTTIN
程序停止,背景程序從終端讀資料時
22
SIGTTOU
程序停止,背景程序想終端寫資料時
23
SIGURG
I/O有緊急資料到達目前程序
24
SIGXCPU
程序的CPU時間片到期
25
SIGXFSZ
檔案大小的超出上限
26
SIGVTALRM
虛拟時鐘逾時
27
SIGPROF
profile時鐘逾時
28
SIGWINCH
視窗大小改變
29
SIGIO
I/O相關
30
SIGPWR
關機
31
SIGSYS
系統調用異常
signal()
"signal.h"信号處理庫提供了signal函數,用來捕獲突發事件。以下是 signal() 函數的文法ads。
signum:可使用信号名(宏)或信号的數字編号,建議使用信号名。
handler:參數 handler 既可以設定為使用者自定義的函數,也可以設定為 SIG_IGN 或 SIG_DFL,SIG_IGN 表示此程序需要忽略該信号,SIG_DFL 則表示設定為系統預設操作。
raise()
有時程序需要向自身發送信号,raise()函數可用于實作這一要求.
sig:需要發送的信号。
sigaction()
除了signal()之外,sigaction()系統調用是設定信号處理方式的另一選擇,雖然 signal()函數簡單好用,而 sigaction()更為複雜,但作為回報,sigaction()也更具靈活性以及移植性。
signum:需要設定的信号,除了 SIGKILL 信号和 SIGSTOP 信号之外的任何信号。
act:參數 act 不為 NULL,則表示需要為信号設定新的處理方式;如果參數 act 為 NULL,則表示無需改變信号目前的處理方式
oldact:參數oldact 不為 NULL,則會将信号之前的處理方式等資訊通過參數 oldact 傳回出來;如果無意擷取此類資訊,那麼可将該參數設定為 NULL。
傳回值:成功傳回 0;失敗将傳回-1,并設定 errno。
struct sigaction 結構體
sa_handler:指定信号處理函數,與 signal()函數的 handler 參數相同。
sa_sigaction:也用于指定信号處理函數,這是一個替代的信号處理函數。
sa_mask:參數 sa_mask 定義了一組信号。
sa_restorer:該成員已過時,不要再使用了。
sa_flags:參數 sa_flags 指定了一組标志,這些标志用于控制信号的處理過程。
kill()
kill()系統調用可将信号發送給指定的程序或程序組中的每一個程序。
pid:參數 pid 為正數的情況下,用于指定接收此信号的程序 pid。
sig:參數 sig 指定需要發送的信号,也可設定為 0,如果參數 sig 設定為 0 則表示不發送信号,但任執行錯誤檢查,這通常可用于檢查參數 pid 指定的程序是否存在。
alarm()
使用 alarm()函數可以設定一個定時器(鬧鐘),當定時器定時時間到時,核心會向程序發送 SIGALRM信号。
seconds:設定定時時間,以秒為機關;如果參數 seconds 等于 0,則表示取消之前設定的 alarm 鬧鐘。
傳回值:如果在調用 alarm()時,之前已經為該程序設定了 alarm 鬧鐘還沒有逾時,則該鬧鐘的剩餘值作為本次 alarm()函數調用的傳回值,之前設定的鬧鐘則被新的替代;否則傳回 0。
pause()
pause()系統調用可以使得程序暫停運作、進入休眠狀态,直到程序捕獲到一個信号為止,隻有執行了信号處理函數并從其傳回時,pause()才傳回,在這種情況下,pause()傳回-1,并且将 errno 設定為EINTR。
使用案例
demo1