linux+向进城发送信号,信号 - it610.com
Linux中有兩種類型信號
常規信號(regular signal):編碼范圍為1~31,同種類型的常規信號如果被發送多次,那么,只有其中的一個發送到接收進城
實時信號(real-time signal):編碼范圍32~64,它與常規信號不通,因為他們必須排隊以便發送的多個信號能被接收到。盡管linux內核不使用實時信號,它還是通過幾個特定的系統調用完全實現了POSIX標準。
與信號相關的最重要的系統調用
kill() ? ? ? ? 向線程組發送一個信號
tkill() ? ? ? ?向進程發送一個信號
tgkill() ? ? ? 向一個特定線程組中的進程發送信號
sigaction() ? ?改變與信號相關的操作
signal() ? ? ? 類似于sigaction()
sigpending() ? 檢查是否有掛起信號
sigprocmask() ?修改阻塞信號的集合
sigsuspend() ? 等待一個信號
信號的一個重要特點是它們可以隨時隨地發送給狀態經常不可預知的進程。發送給非運行進程的信號必須由內核保存,直到進程恢復執行。
內核區分信號傳遞的兩個不同階段:
信號產生
內核更新目標進程的數據結構以表示一個新信號已被發送。
信號傳遞
內核強迫目標進程通過以下方式對信號做出反應:或改變目標進程的執行狀態,或開始執行一個特定的信號處理程序,或者兩者都是。
已經產生但還沒有傳遞的信號稱為掛起信號(pending signal)。任何時候,一個進程僅存在給定類型的一個掛起信號,同一進程同種類型的其他信號不被排隊,只被簡單的丟棄。但是,實時信號時不同的:同種類型的掛起信號可以多個。
盡管信號表項比較直觀,但內核實現相當復雜:
1、記住每個進程阻塞哪些信號
2、當從內核態切換到用戶態時,對任何一個進程都要檢查是否有一個信號到達。這幾乎在每個定時器中斷都發送
3、確定是否可以忽略信號。這發生在下列所有條件都滿足時:
a、目標進程沒有被另一個進程跟蹤
b、信號沒有被目標進程阻塞
c、信號被目標進程屏蔽
4、處理這樣的信號,即信號可能在進程運行期間的任一時刻請求把進程切換到一個信號處理函數,并在這個函數返回后恢復原來執行的上下文。
進程以三種方式對一個信號做出應答:
1、顯示地忽略信號
2、執行與信號相關的缺省操作
3、通過調用相應的信號處理函數捕獲信號
注意,對一個信號的阻塞和忽略是不同的:只要信號被阻塞,它就不被傳遞;只有信號解除阻塞后才傳遞它。而一個被忽略的信號總是被傳遞,只是沒有進一步的操作。
SIGKILL和SIGSTOP信號不可以被顯式地忽略、捕獲或阻塞,因此,通常必須執行它們的缺省操作。
POSIX標準對多線程應用的信號處理有一些嚴格的要求:
1、信號處理程序必須在多線程應用的所有線程之間共享;不過,每個線程必須有自己的掛起信號掩碼和阻塞信號掩碼
2、每個發送給多線程應用的信號僅傳送給一個線程,這個線程是由內核在從不阻塞該信號的線程中隨意選擇出來的
3、如果向多線程應用發送了一個致命的信號,那么內核將殺死該應用的所有線程,而不僅僅是殺死接收信號的那個線程。
task_struct線程描述符中與信號相關的字段
struct signal_struct *signal;
struct sighand_struct *sighand;
struct sigpending pending;
產生信號
很多內核函數都會產生信號:它們完成信號處理第一步的工作,即根據需要更新一個或多個進程的描述符。它們不直接執行第二步的信號傳遞操作,而是可能可能根據信號的類型和目標進程的狀態喚醒一下進程,并促使這些進程接收信號。
當發送給進程一個信號時,這個信號可能來自內核,也可能來自另一個進程
傳遞信號
假定內核已經注意到一個信號的到來,并調用前面介紹的函數為接收此信號的進程準備描述符。但萬一這個進程在那一刻并不在CPU運行,內核就延遲傳遞函數的任務。那么如何確保進程的掛起信號得到處理呢?
內核在運行進程恢復用戶態下的執行前,檢查進程TIF_SIGPENDING標志的值。每當內核處理完一個中斷或異常時,就檢查是否存在掛起的信號。
捕獲信號
上圖說明了有關捕獲一個信號的函數的執行流。一個非阻塞的信號發送給一個進程。當中斷或異常發生時,進程切換到內核態。正要返回到用戶態前,內核執行do_signal()函數,這個函數又依次處理信號和建立用戶態堆棧。當進程又切換到用戶態時因為信號處理程序的起始地址被強制放進程序計數器中,因此開始執行信號處理程序。當處理程序終止時,setup_frame()函數放在用戶態堆棧中的返回代碼被執行。這個代碼調用sigreturn()系統調用,相應的服務例程把正常程序的用戶態堆棧硬件上下文拷貝到內核態堆棧,并把用戶態堆?;謴偷皆瓉淼臓顟B。當這個系統調用結束時,普通進程就因此能恢復自己的執行。
總結
以上是生活随笔為你收集整理的linux+向进城发送信号,信号 - it610.com的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux插光驱自动重启,Linux两种
- 下一篇: linux32安装pgsql,Linux