信号处理的流程linux,linux信号处理机制
學習一下信號的處理機制。
一、信號的產生
信號是有可能來自內核,也有可能來自進程。當然,最根本的來源是信號產生函數。
其實就是通過內核更新目標進程的數據結構以表示一個信號已經被發送。
其中為進程產生信號的函數有:
函數名
說明
send_sig()
向單一進程發送信號
send_sig_info()
與send_sig()類似,只是還使用siginfo_t結構中的擴展信息
force_sig()
發送既不能被進程顯示忽略,也不能被進程阻塞的信號
force_sig_info()
與force_sig()類似,只是還使用siginfo_t結構中的擴展信息
force_sig_specific()
與force_sig()類似,但是優化了對SIGSTOP和SIGKILL信號的處理
sys_tkill()
tkill()的系統調用處理函數
sys_tgkill()
tgkill()的系統調用處理函數
為線程組產生信號的函數有:
函數名
說明
send_group_sig_info()
向某一個線程組發送信號,該線程組由它的一個成員進程的描述符來識別
kill_pg()
想一個進程組中的所有線程組發送信號
kill_pg_info()
與kill_pg()類似,只是還使用siginfo_t結構中的擴展信息
kill_pg_proc()
向某一個線程組發送信號,該線程組由它的一個成員進程的pid來識別
kill_pg_proc_info()
與kill_pg_proc ()類似,只是還使用siginfo_t結構中的擴展信息
sys_kill()
kill()的系統調用處理函數
sys_rt_sigqueueinfo()
rt_sigqueueinfo()的系統調用處理函數
二、信號的傳遞
當內核注意到一個信號到來,并調用相關函數為接受此信號的進程準備描述符。但是萬一這個進程那一刻并不在CPU上運行,內核就只能延遲傳遞信號的任務。因此這里就有兩個queue,分別儲存私有信號和共享信號。每當內核處理完一個中斷或異常時,就檢查是否存在掛起信號(即檢查TIF_SIGPENDING)。如果存在掛起信號,那么內核就會調用do_signal函數。這個函數會循環執行,直到將兩個隊列中的所有非阻塞信號都處理完才退出。
既然直到do_signal()整個過程干了什么,那么接下來就描述一下對于每一個信號,do_signal會進行怎么樣的處理。首先,它會檢查current接收進程是否受到其他一些進程的監控;在肯定的情況下,do_signal函數調用相關函數讓監控進程知道current接收進程的信號處理;然后do_signal()要把處理信號的k_sigaction數據結構的地址賦值給局部變量ka,再根據ka內容來執行三種操作:忽略信號、執行缺省操作或執行信號處理程序。
三、信號的處理
在第二點中已經提到了進程收到信號之后的可能三種操作。這里只描述執行信號處理程序的過程。這個過程比較復雜。
如果信號有一個專門的處理程序,那么do_signal()函數就會通過調用handle_signal()來強迫該處理程序執行。但是信號處理程序都是用戶態進程所定義的,并包含在用戶態的代碼段中。handle_signal()函數運行在內核態,而信號處理程序運行在用戶態,這就意味著在當前進程恢復“正常”執行之前,它首先必須執行用戶態的信號處理程序。而且當內核打算恢復進程的正常執行時,內核態堆棧不再包含被中斷程序的硬件上下文,因為每當從內核態向用戶態轉換時內核態堆棧都會被清空。而如果信號處理程序調用了系統調用,那么這個執行過程的復雜程度就更高了。
Linux對此過程的解決方案是把保存在內核態堆棧中的硬件上下文拷貝到當前進程的用戶態堆棧中。用戶態堆棧也以這樣的方式被修改,當信號處理程序終止時,自動調用sigreturn()系統調用把這個硬件上下文拷貝回內核態堆棧中,并回復用戶態堆棧中原來的內容。
該過程流程圖如下:
更多的細節不在此描述了。
總結
以上是生活随笔為你收集整理的信号处理的流程linux,linux信号处理机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux耳机检测,Audio Jack
- 下一篇: Win7内存评分规则揭秘:0到10分,你