信號基礎知識【菜鳥學習日記】

信號與中斷

Linux信號是一種進程間異步的通信機制,可以理解爲是一種“軟中斷”。
信號可以使一個正在運行的進程被異步打斷,然後轉而去處理一個突發的事件。
異步事件是不可預見的,只能通過某些特定的方式來預防,或者說,當該異步事件發生時根據原來設定好的的相應操作去完成。


幾種常見信號處理

  • SIGCHLD:子進程退出時會給父進程發送該信號。父進程可以根據該信號來完成對子進程PCB資源的回收
  • SIGSTOPSIGKILL:這兩個信號不能被屏蔽、安裝,也就是說,用戶不能自定義這兩個信號的處理
  • SIGSTOPSIGCONT:這兩個信號是配對的。一個進程在收到SIGSTOP後會暫停執行,進入暫停狀態,並屏蔽SIGKILL所有的信號。當該進程收到SIGCONT信號後會繼續執行
  • 信號可以喚醒被中斷的進程,例如,可以喚醒調用sleep()函數進入阻塞狀態的進程

信號的安裝到註銷

1、在目標進程中安裝該信號,即設置如果進程捕獲到該信號時執行的操作代碼。

  • Linux採用signalsigaction系統調用來完成該操作

2、 信號被某個進程產生,同時設置此信號的目的進程(一般爲目標進程的pid),然後由操作系統管理。

  • Linux採用kill()、arise()、alarm()等系統調用來完成。

3、信號在目的進程被註冊。
操作系統將信號添加到目的進程的PCB相關的數據結構中。

  • 未決信號:信號已經產生,但因目標進程暫時屏蔽該信號而不能被目標進程捕獲的信號
  • 每個進程的PCB(task_struct結構)中有一個未決信號的數據成員
  • 該成員聲明如下:
struct sigpending pending;
struct sigpending
{
   struct sigqueue *head,**tail;//指向未決信號隊列
   sigset_t signal;//信號集
}
//第一個和第二個成員分別指向一個sigqueue類型的未決信號隊列的隊首和隊尾
//第三個成員是進程中所有未決信號集

信號鏈中的每個sigqueue結構體描述一個特定信號所攜帶的信號,並指向下一個sigqueue結構
該結構聲明如下:

//sigqueue結構
struct  sigqueue
{
    struct  sigqueue  *next;
    siginfo_t info;
}
簡單來說,信號在進程中註冊指的就是將相應的信號值加入到進程的未決信號集中(sigpending結構的第二個成員sigset_t signal),並且將該信號所攜帶的其它信號信息保留到未決信號隊列的某個sigqueue結構體中。
只要信號在進程的未決信號集中,表明進程已經知道這些信號的存在,但還沒來得及處理,或者該信號被進程屏蔽。(函數sigpending可取當前進程的屏蔽信號和未決信號)

4、信號在進程中註銷
進程在執行信號相對應的處理函數之前,首先要發此信號在進程中註銷(該信號在只佔用一個sigqueue結構)。
目標進程在執行過程中,會檢測是不是還有信號等待處理。進程每次從系統空間返回到用戶空間時都會做這樣的檢查。如果存在未決信號等待處理並且該信號沒有被進程屏蔽,則在運行該信號相應的的處理函數前,將此信號在未決信號鏈中佔有的結構卸載掉。


5、信號註銷後。
進程在信號註銷後,目的進程根據當前進程對此信號設置的處理方式,暫時終止當前進程代碼的執行,保護上下文(主要包括臨時寄存器數據、當前程序位置以及當前CPU的狀態)、轉而去執行信號的處理函數,即捕獲信號,執行完成後再恢復到被中斷的位置繼續執行。


發送信號

發送信號是指一個進程向另一個進程發送某個信號值,但實際上並不是直接發送的,而是有操縱系統轉發的。

信號的來源有很多種可能:

  1. 用戶按終端鍵產生的信號,如:在終端按“Ctrl+c”,產生一個終止信號。這是產生中斷的一種方法
  2. 硬件異常。如:對執行一個無效的存儲訪問的進程產生一個SIGSEGV
  3. 終止進程信號。其它進程調用kill()函數可將信號發送給另一個進程或進程組。常用次命令終止一個失控的進程。
  4. 軟件異常產生信號。當檢測到某種軟件條件已經發生,並將其通知有關進程是也會產生信號。例如,SIGPIPE(在管道的讀進程已終止,後一個進程寫此管道)

下圖是使用kill命令殺死當前終端的
這裏寫圖片描述


根據發送信號的不同,產生一個信號需要調用的函數也不同
  • 傳遞一個信號給指定的進程:kill()函數
  • 傳遞一個信號給當前進程:raise()函數
  • 喚醒一個進程和設置定時alarm函數
發佈了78 篇原創文章 · 獲贊 15 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章