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