信號是Linux編程中非常重要的部分,本文將詳細介紹信號機制的基本概念、Linux對信號機制的大致實現方法、如何使用信號,以及有關信號的幾個系統調用。
信號機制是進程之間相互傳遞消息的一種方法,信號全稱為軟中斷信號,也有人稱作軟中斷。從它的命名可以看出,它的實質和使用很象中斷。所以,信號可以說是進程控制的一部分。
一、信號的基本概念
本節先介紹信號的一些基本概念,然後給出一些基本的信號類型和信號對應的事件。基本概念對於理解和使用信號,對於理解信號機制都特別重要。下面就來看看什麼是信號。
1、基本概念
軟中斷信號(signal,又簡稱為信號)用來通知進程發生了異步事件。進程之間可以互相通過系統調用kill發送軟中斷信號。內核也可以因為內部事件而給進程發送信號,通知進程發生了某個事件。注意,信號只是用來通知某進程發生了什麼事件,並不給該進程傳遞任何數據。
收 到信號的進程對各種信號有不同的處理方法。處理方法可以分為三類:第一種是類似中斷的處理程序,對於需要處理的信號,進程可以指定處理函數,由該函數來處 理。第二種方法是,忽略某個信號,對該信號不做任何處理,就象未發生過一樣。第三種方法是,對該信號的處理保留系統的默認值,這種缺省操作,對大部分的信 號的缺省操作是使得進程終止。進程通過系統調用signal來指定進程對某個信號的處理行為。
在進程表的表項中有一個軟中斷信號域,該域中每一位對應一個信號,當有信號發送給進程時,對應位置位。由此可以看出,進程對不同的信號可以同時保留,但對於同一個信號,進程並不知道在處理之前來過多少個。
2、信號的類型
發出信號的原因很多,這裡按發出信號的原因簡單分類,以了解各種信號:
(1) 與進程終止相關的信號。當進程退出,或者子進程終止時,發出這類信號。
(2) 與進程例外事件相關的信號。如進程越界,或企圖寫一個只讀的內存區域(如程序正文區),或執行一個特權指令及其他各種硬件錯誤。
(3) 與在系統調用期間遇到不可恢復條件相關的信號。如執行系統調用exec時,原有資源已經釋放,而目前系統資源又已經耗盡。
(4) 與執行系統調用時遇到非預測錯誤條件相關的信號。如執行一個並不存在的系統調用。
(5) 在用戶態下的進程發出的信號。如進程調用系統調用kill向其他進程發送信號。
(6) 與終端交互相關的信號。如用戶關閉一個終端,或按下break鍵等情況。
(7) 跟蹤進程執行的信號。
Linux支持的信號列表如下。很多信號是與機器的體系結構相關的,首先列出的是POSIX.1中列出的信號:
信號 值 處理動作 發出信號的原因
----------------------------------------------------------------------
SIGHUP 1 A 終端掛起或者控制進程終止
SIGINT 2 A 鍵盤中斷(如break鍵被按下)
SIGQUIT 3 C 鍵盤的退出鍵被按下
SIGILL 4 C 非法指令
SIGABRT 6 C 由abort(3)發出的退出指令
SIGFPE 8 C 浮點異常
SIGKILL 9 AEF Kill信號
SIGSEGV 11 C 無效的內存引用
SIGPIPE 13 A 管道破裂: 寫一個沒有讀端口的管道
SIGALRM 14 A 由alarm(2)發出的信號
SIGTERM 15 A 終止信號
SIGUSR1 30,10,16 A 用戶自定義信號1
SIGUSR2 31,12,17 A 用戶自定義信號2
SIGCHLD 20,17,18 B 子進程結束信號
SIGCONT 19,18,25 進程繼續(曾被停止的進程)
SIGSTOP 17,19,23 DEF 終止進程
SIGTSTP 18,20,24 D 控制終端(tty)上按下停止鍵
SIGTTIN 21,21,26 D 後台進程企圖從控制終端讀
SIGTTOU 22,22,27 D 後台進程企圖從控制終端寫
下面的信號沒在POSIX.1中列出,而在SUSv2列出
信號 值 處理動作 發出信號的原因
--------------------------------------------------------------------
SIGBUS 10,7,10 C 總線錯誤(錯誤的內存訪問)
SIGPOLL A Sys V定義的Pollable事件,與SIGIO同義
SIGPROF 27,27,29 A Profiling定時器到
SIGSYS 12,-,12 C 無效的系統調用 (SVID)
SIGTRAP 5 C 跟蹤/斷點捕獲
SIGURG 16,23,21 B Socket出現緊急條件(4.2 BSD)
SIGVTALRM 26,26,28 A 實際時間報警時鐘信號(4.2 BSD)
SIGXCPU 24,24,30 C 超出設定的CPU時間限制(4.2 BSD)
SIGXFSZ 25,25,31 C 超出設定的文件大小限制(4.2 BSD)
(對於SIGSYS,SIGXCPU,SIGXFSZ,以及某些機器體系結構下的SIGBUS,Linux缺省的動作是A (terminate),SUSv2 是C (terminate and dump core))。
下面是其它的一些信號
信號 值 處理動作 發出信號的原因
----------------------------------------------------------------------
SIGIOT 6 C IO捕獲指令,與SIGABRT同義
SIGEMT 7,-,7
SIGSTKFLT -,16,- A 協處理器堆棧錯誤
SIGIO 23,29,22 A 某I/O操作現在可以進行了(4.2 BSD)
SIGCLD -,-,18 A 與SIGCHLD同義
SIGPWR 29,30,19 A 電源故障(System V)
SIGINFO 29,-,- A 與SIGPWR同義
SIGLOST -,-,- A 文件鎖丟失
SIGWINCH 28,28,20 B 窗口大小改變(4.3 BSD, Sun)
SIGUNUSED -,31,- A 未使用的信號(will be SIGSYS)
(在這裡,- 表示信號沒有實現;有三個值給出的含義為,第一個值通常在Alpha和Sparc上有效,中間的值對應i386和ppc以及sh,最後一個值對應mips。信號29在Alpha上為SIGINFO / SIGPWR ,在Sparc上為SIGLOST。)
處理動作一項中的字母含義如下
A 缺省的動作是終止進程
B 缺省的動作是忽略此信號
C 缺省的動作是終止進程並進行內核映像轉儲(dump core)
D 缺省的動作是停止進程
E 信號不能被捕獲
F 信號不能被忽略
上 面介紹的信號是常見系統所支持的。以表格的形式介紹了各種信號的名稱、作用及其在默認情況下的處理動作。各種默認處理動作的含義是:終止程序是指進程退 出;忽略該信號是將該信號丟棄,不做處理;停止程序是指程序掛起,進入停止狀況以後還能重新進行下去,一般是在調試的過程中(例如ptrace系統調 用);內核映像轉儲是指將進程數據在內存的映像和進程在內核結構中存儲的部分內容以一定格式轉儲到文件系統,並且進程退出執行,這樣做的好處是為程序員提 供了方便,使得他們可以得到進程當時執行時的數據值,允許他們確定轉儲的原因,並且可以調試他們的程序。