華清遠見嵌入式學院上海中心
講師。一、訊號及訊號**
訊號本質
訊號是在軟體層次上對中斷機制的一種模擬,在原理上,乙個程序收到乙個訊號與處理器收到乙個中斷請求可以說是一樣的。訊號是非同步的,乙個程序不必通過任何操作來等待訊號的到達,事實上,程序也不知道訊號到底什麼時候到達。
訊號是程序間通訊機制中唯一的非同步通訊機制,可以看作是非同步通知,通知接收訊號的程序有哪些事情發生了。訊號機制經過posix實時擴充套件後,功能更加強大,除了基本通知功能外,還可以傳遞附加資訊。
訊號**
二、訊號的種類
可以從兩個不同的分類角度對訊號進行分類:(1)可靠性方面:可靠訊號與不可靠訊號,(2)與時間的關係上:實時訊號與非實時訊號。在《linux環境程序間通訊(一):管道及有名管道》的附1中列出了系統所支援的所有訊號。
1、可靠訊號與不可靠訊號
"不可靠訊號"
linux訊號機制基本上是從unix系統中繼承過來的。早期unix系統中的訊號機制比較簡單和原始,後來在實踐中暴露出一些問題,因此,把那些建立在早期機制上的訊號叫做"不可靠訊號",訊號值小於sigrtmin(red hat7.2中,sigrtmin=32,sigrtmax=63)的訊號都是不可靠訊號。這就是"不可靠訊號"的**。它的主要問題是:
·程序每次處理訊號後,就將對訊號的響應設定為預設動作。在某些情況下,將導致對訊號的錯誤處理;因此,使用者如果不希望這樣的操作,那麼就要在訊號處理函式結尾再一次呼叫signal(),重新安裝該訊號。
·訊號可能丟失,後面將對此詳細闡述。
因此,早期unix下的不可靠訊號主要指的是程序可能對訊號做出錯誤的反應以及訊號可能丟失。
linux支援不可靠訊號,但是對不可靠訊號機制做了改進:在呼叫完訊號處理函式後,不必重新呼叫該訊號的安裝函式(訊號安裝函式是在可靠機制上的實現)。因此,linux下的不可靠訊號問題主要指的是訊號可能丟失。
"可靠訊號"
隨著時間的發展,實踐證明了有必要對訊號的原始機制加以改進和擴充。所以,後來出現的各種unix版本分別在這方面進行了研究,力圖實現"可靠訊號"。由於原來定義的訊號已有許多應用,不好再做改動,最終只好又新增加了一些訊號,並在一開始就把它們定義為可靠訊號,這些訊號支援排隊,不會丟失。同時,訊號的傳送和安裝也出現了新版本:訊號傳送函式sigqueue()及訊號安裝函式sigaction()。posix.4對可靠訊號機制做了標準化。但是,posix只對可靠訊號機制應具有的功能以及訊號機制的對外介面做了標準化,對訊號機制的實現沒有作具體的規定。
訊號值位於sigrtmin和sigrtmax之間的訊號都是可靠訊號,可靠訊號克服了訊號可能丟失的問題。linux在支援新版本的訊號安裝函式sigation()以及訊號傳送函式sigqueue()的同時,仍然支援早期的signal()訊號安裝函式,支援訊號傳送函式kill()。
注:不要有這樣的誤解:由sigqueue()傳送、sigaction安裝的訊號就是可靠的。事實上,可靠訊號是指後來新增的新訊號(訊號值位於sigrtmin及sigrtmax之間);不可靠訊號是訊號值小於sigrtmin的訊號。訊號的可靠與不可靠只與訊號值有關,與訊號的傳送及安裝函式無關。目前linux中的signal()是通過sigation()函式實現的,因此,即使通過signal()安裝的訊號,在訊號處理函式的結尾也不必再呼叫一次訊號安裝函式。同時,由signal()安裝的實時訊號支援排隊,同樣不會丟失。
對於目前linux的兩個訊號安裝函式:signal()及sigaction()來說,它們都不能把sigrtmin以前的訊號變成可靠訊號(都不支援排隊,仍有可能丟失,仍然是不可靠訊號),而且對sigrtmin以後的訊號都支援排隊。這兩個函式的最大區別在於,經過sigaction安裝的訊號都能傳遞資訊給訊號處理函式(對所有訊號這一點都成立),而經過signal安裝的訊號卻不能向訊號處理函式傳遞資訊。對於訊號傳送函式來說也是一樣的。
三、訊號的安裝(設定訊號關聯動作)
如果程序要處理某一訊號,那麼就要在程序中安裝該訊號。安裝訊號主要用來確定訊號值及程序針對該訊號值的動作之間的對映關係,即程序將要處理哪個訊號;該訊號被傳遞給程序時,將執行何種操作。
linux主要有兩個函式實現訊號的安裝:signal()、sigaction()。其中signal()在可靠訊號系統呼叫的基礎上實現,是庫函式。它只有兩個引數,不支援訊號傳遞資訊,主要是用於前32種非實時訊號的安裝;而sigaction()是較新的函式(由兩個系統呼叫實現:sys_signal以及sys_rt_sigaction),有三個引數,支援訊號傳遞資訊,主要用來與 sigqueue()系統呼叫配合使用,當然,sigaction()同樣支援非實時訊號的安裝。sigaction()優於signal()主要體現在支援訊號帶有引數。
1、signal()
#include
void (*signal(int signum, void (*handler))(int)))(int);
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler));
第乙個引數指定訊號的值,第二個引數指定針對前面訊號值的處理,可以忽略該訊號(引數設為sig_ign);可以採用系統預設方式處理訊號(引數設為sig_dfl);也可以自己實現處理方式(引數指定乙個函式位址)。
如果signal()呼叫成功,返回最後一次為安裝訊號signum而呼叫signal()時的handler值;失敗則返回sig_err。
2、sigaction()
#include
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));
sigaction函式用於改變程序接收到特定訊號後的行為。該函式的第乙個引數為訊號的值,可以為除sigkill及sigstop外的任何乙個特定有效的訊號(為這兩個訊號定義自己的處理函式,將導致訊號安裝錯誤)。第二個引數是指向結構sigaction的乙個例項的指標,在結構sigaction的例項中,指定了對特定訊號的處理,可以為空,程序會以預設方式對訊號處理;第三個引數oldact指向的物件用來儲存原來對相應訊號的處理,可指定oldact為null。如果把第
二、第三個引數都設為null,那麼該函式可用於檢查訊號的有效性。
第二個引數最為重要,其中包含了對指定訊號的處理、訊號所傳遞的資訊、訊號處理函式執行過程中應遮蔽掉哪些函式等等。
Linux訊號簡介
1 sighup 本訊號在使用者終端糾纏 孱弱或非正常 收束時發出,通常是在終端的控 制過程結束時,命令同一session內的各個勞動,那時它們與占有終端 不再關聯.2 sigint 程式終止 interrupt 訊號,在使用者鍵入intr字元 通常是ctrl c 時發出 3 sigquit 和si...
Linux訊號簡介
linux訊號簡介 1 sighup 本訊號在使用者終端連線 正常或非正常 結束時發出,通常是在終端的控制程序結束時,通知同一session內的各個作業,這時它們與控制終端不再關聯.2 sigint 程式終止 interrupt 訊號,在使用者鍵入intr字元 通常是ctrl c 時發出 3 sig...
linux訊號簡介
kill l可以列出系統的訊號名稱 linux訊號簡介 1 sighup 本訊號在使用者終端連線 正常或非正常 結束時發出,通常是在終端的控制程序結束時,通知同一session內的各個作業,這時它們與控制終端不再關聯.2 sigint 程式終止 interrupt 訊號,在使用者鍵入intr字元 通...