訊號之不可靠的訊號及中斷的系統呼叫

2022-05-04 20:09:18 字數 1462 閱讀 8690

在早期的unix版本中,訊號是不可靠的。不可靠在這裡指的是,訊號可能會丟失:乙個訊號發生了,但程序卻可能一直不知道這一點

早期版本中的乙個問題是在程序每次接到訊號對其進行處理時,隨即將該訊號動作復位為預設值(經測試,發現我現在用的red hat linux 2.6.18也是這樣處理的。)。在描述這些早期系統的程式設計書籍中,有乙個經典例項,它與如何處理中斷訊號相關,其**與下面所示的相似:

int    sig_int();                /*

my signal handling function

*/...

signal(sigint, sig_int);

/*establish handler

*/...

sig_int()

view code

(由於早期的c語言版本不支援iso c的void資料型別,所以將訊號處理程式宣告為int型別。)

這段**的乙個問題是:從訊號發生之後到在訊號處理程式中呼叫signal函式之前這段時間中有乙個時間視窗。在此段時間中,可能發生另一次中斷訊號。第二個中斷訊號會導致執行預設動作,而針對中斷訊號的預設動作是終止該程序。這種型別的程式段在大多數情況下會正常工作,使得我們認為它們是正確無誤的,而實際上並非如此。

早期unix系統的乙個特性是:如果程序在執行乙個低速系統呼叫而阻塞期間捕捉到乙個訊號,則該系統呼叫就被中斷不再繼續執行。該系統呼叫返回出錯,其errno被設定為eintr

在這裡,我們必須區分系統呼叫和函式。當捕捉到某個訊號時,被中斷的是核心中執行的系統呼叫

為了支援這種特性,將系統呼叫分成兩類:低速系統呼叫和其他系統呼叫。低速系統呼叫是可能會使程序永遠阻塞的一類系統呼叫,它們包括:

在這些低速系統呼叫中,乙個值得注意的例外是與磁碟i/o有關的系統呼叫。雖然讀寫乙個磁碟檔案可能暫時阻塞呼叫者(在磁碟驅動器將請求排入佇列,然後在適當時間執行請求期間),但是除非發生硬體錯誤,i/o操作總會很快返回,並使呼叫者不再處於阻塞狀態。

again:

if ((n = read(fd, buf, buffsize) < 0

)

為了幫助應用程式使其不必處理被中斷的系統呼叫,4.2bsd引入了某些被中斷系統呼叫的自動重啟動。自動重啟動的系統呼叫包括ioctl、read、readv、write、writev、wait和waitpid。其中,前5個函式只有對低速裝置進行操作時才會被訊號中斷。而wait和waitpid在捕捉到訊號時總是被中斷。4.3bsd允許程序基於每個訊號禁用此功能。

本篇博文內容摘自《unix環境高階程式設計》(第二版),僅作個人學習記錄所用。關於本書可參考:

訊號及訊號處理(二) 可靠訊號與不可靠訊號

一 可靠訊號與不可靠訊號有哪些?sighup 1號 至 sigsys 31號 之間的訊號都是繼承自unix系統,是不可靠訊號,也稱為非實時訊號 sigrtmin 33號 與 sigrtmax 64號 之間的訊號,它們都是可靠訊號,也稱為實時訊號 二 什麼是可靠訊號?可靠性是指訊號是否會丟失,即該訊號...

24 可靠訊號與不可靠訊號

以下整理 自 1 1 可靠訊號與不可靠訊號 1 訊號值小於 sigrtmin red hat 7.2 中,sigrtmin 32 sigrtmax 63 的訊號都是不可靠訊號。主要問題如下 程序每次處理訊號後,就將對訊號的響應設定為預設動作。在某些情況下,將導致對訊號的錯誤處理 因此,使用者如果不希...

學習筆記 可靠訊號 不可靠訊號

不可靠訊號pk可靠訊號 q linux訊號機制基本上是從unix系統中繼承過來的。早期unix系統中的訊號機制比較簡單和原始,後來在實踐中暴露出一些問題,它的主要問題是 q 程序每次處理訊號後,就將對訊號的響應設定為預設動作。在某些情況下,將導致對訊號的錯誤處理 因此,使用者如果不希望這樣的操作,那...