信號作為異步進程的通信方式,在實際應用中是方便而實用的。但是,也應該注意到在使用信號時的潛在危險。在此簡單介紹幾種可能引發錯誤的具體情況,希望在實際進行信號處理時特別注意。
當注冊了一個信號處理函數時,可能會對某些系統調用進行修改。通常來講,它們本來應是不受信號的影響,但由於注冊了一個信號處理函數,系統可能會認為在一個信號到來時需要中斷原系統調用。當這種情況發生時,原系統調用被終止,返回調用失敗值,同時errno將被設置為EINTR。當然有一些時候,確實希望系統如此處理,但在另一些情況下,並不希望這樣,因為有可能由於返回的錯誤代碼使其後的進程無法按所希望的方向進行,甚至可能由於在後續的運行中未對出錯返回作出相應處理而認為調用成功,從而導致數據的丟失。因此,建議使用函數sigaction 設置SA_RESTART 標志來防止這一情況的發生。
另一種情況是,在執行用戶自行設置的信號處理函數時,也可能會有另一個信號產生。這時可能造成第一個調用被中斷而進行第二個信號處理函數的調用。當第二個調用結束後再繼續第一個調用的執行。這將會對函數的運行造成影響,特別是對使用了靜態變量的程序。對這種情況,可以調用函數sigaction 設置SA_NODEFER 來阻塞第二個信號。
此外,在一個繁忙的系統中,對於涉及到系統時間的操作,可能會與預期的效果有所不同。例如在alarm 調用後調用了函數pause,希望在alarm 設定的報警發生時結束pause 狀態。但由於系統過於繁忙而使此進程分到的時間片過少,當報警發生時,函數pause 還未被調用到,則當函數pause 被調用到時將可能造成進程被永遠掛起。
-----(以上摘自《linux環境c編程指南》)