經常我們在睡眠的代碼中會看到這樣的例子:

    if (signal_pending(current)) {

     ret = - ERESTARTSYS ;

     return ret;

    }

    關於  - ERESTARTSYS 到底是什麼意思?  

    -ERESTARTSYS表示信號函數處理完畢後重新執行信號函數前的某個系統調用

也就是說如果信號函數前有發生系統調用在調度用戶信號函數之前內核會檢查系統調用的返回值看看是不是因為這個信號而中斷了系統調用
如果返回值-ERESTARTSYS並且當前調度的信號具備-ERESTARTSYS屬性系統就會在用戶信號函數返回之後再執行該系統調用

 

這個過程不必深究你就知道上層的庫函數當收到 -ERESTARTSYS 這個返回值後linux來講會自動的重新調用這個調用就可以了

 

至於
signal_pending ( current )―――》檢查當前進程是否有信號處理,返回不為0表示有信號需要處理。

情景分析:
1,當一個系統調用處於等待狀態時,比如等待輸入緩衝區不為空,此時產生了信號,這個信號僅僅是在該進程的thread_info結構中標識一下,就是所謂的“發信號” ,然後喚醒進程的系統調用,系統調用醒來後,此時僅僅用signal_pending()檢查一下是否有信號,這裡,不處理信號的,當此時有信號,系統調用返回ERESTARTSYS,在從系統調用的返回用戶空間時,會根據thread_info中信號標識位調用相應的信號處理函數,這裡就是所謂的“接收信號”,
對於Linux,上層庫函數會根據系統調用的ERESTARTSYS返回值重啟該系統調用,而對於Solaris則會讓系統調用失敗,在Linux中,重啟的系統調用會再次檢查緩衝區,為空,說明剛才的信號不是緩衝區有數據了的信號,繼續等待,重複剛才的過程,不為空,就可以直接處理數據,系統調用正常結束
注:“發信號”僅僅是標識thread_info,系統調用醒來檢查信號,僅僅是
signal_pending()判斷一下thread_info中是否有任何一個信號標識,真正的“接受信號”是從系統調用返回時,或者異常處理程序返回時,比如每次的時鐘中斷處理函數返回時,檢查thread_info中具體哪個信號,調用相應處理程序
補:對於Solaris,上面的情況,read在等,緩衝區滿了,喚醒read進程,不同通過我們這裡所談的"信號"

BB 發表在 痞客邦 PIXNET 留言(0) 人氣()