基本概念
概述
信號是事件發(fā)生時對進(jìn)程的通知機(jī)制沪停,有時也稱為軟件中斷,信號與硬件中斷相似之處在于打斷了程序執(zhí)行的正常流程端三,大多數(shù)情況下泻轰,無法預(yù)測信號到達(dá)的精確時間浮声。
一個具有合適權(quán)限的進(jìn)程能夠向另一進(jìn)程發(fā)送信號,信號的這一用法可作為一種同步技術(shù)然痊,甚至是進(jìn)程通信IPC的原始形式剧浸。進(jìn)程也可以向自身發(fā)送信號矗钟。然而發(fā)生進(jìn)程的諸多信號吨艇,通常都是源于內(nèi)核冯吓。
引發(fā)內(nèi)核為進(jìn)程產(chǎn)生信號的各類事件如下:
- 硬件發(fā)生異常:例子包括執(zhí)行一條異常的機(jī)器語言指令疮跑,如被0除祖娘,或者引用了無法訪問的內(nèi)存區(qū)域
- 用戶鍵入能夠產(chǎn)生信號的中斷特殊字符:包括中斷字符(Control-C)
- 發(fā)生了軟件事件:列入渐苏,針對文件描述符的輸出變?yōu)橛行д裕{(diào)整了中斷窗口大小公黑、定時器到期、進(jìn)程執(zhí)行的CPU時間超限人断、或者改進(jìn)程的某個子進(jìn)程退出
信號分兩大類:
- 內(nèi)核向進(jìn)程通知事件恶迈,構(gòu)成所謂傳統(tǒng)或者標(biāo)準(zhǔn)信號,編號1~31
- 實(shí)時信號
信號產(chǎn)生后奈附,會稍后被傳遞給某一進(jìn)行煮剧,而進(jìn)程也會采取某些措施來響應(yīng)信號勉盅,在產(chǎn)生和到達(dá)期間,信號處于等待狀態(tài)挑胸。如果需要確保一段代碼不為傳遞來的信號所中斷嗜暴,可將信號添加到信號掩碼中议蟆,會阻止該信號的到達(dá)咐容,直到稍后對其解除阻塞路狮。
信號到達(dá)后,進(jìn)程視具體信號執(zhí)行如下默認(rèn)操作之一:
- 忽略信號:內(nèi)核將信號丟失
- 終止進(jìn)程
- 產(chǎn)生核心轉(zhuǎn)儲文件蔚约,同時進(jìn)程終止:核心轉(zhuǎn)儲文件包含對進(jìn)程虛擬內(nèi)存的鏡像奄妨,可將其加載到調(diào)試器中以檢查進(jìn)程終止時的狀態(tài)
- 停止進(jìn)程:暫停進(jìn)程的執(zhí)行
- 于之前暫停后再度恢復(fù)進(jìn)程的執(zhí)行
程序能改變信號到達(dá)時的響應(yīng)行為,稱為對信號的處置設(shè)置:
- 采取默認(rèn)行為
- 忽略信號
- 執(zhí)行信號處理器(信號處理器程序是由程序員編寫的函數(shù)苹祟,用于為響應(yīng)傳遞來的信號而執(zhí)行適當(dāng)任務(wù))
信號類型和默認(rèn)行為
Linux標(biāo)準(zhǔn)信號如下:
- SIGABRT:進(jìn)程調(diào)用abort()函數(shù)時砸抛,系統(tǒng)向進(jìn)程發(fā)送該信號评雌,默認(rèn)情況下,該信號會終止進(jìn)程直焙,并產(chǎn)生核心轉(zhuǎn)儲文件景东,用于調(diào)試
- SIGALRM:經(jīng)調(diào)用alarm()或setitimer()而設(shè)置的實(shí)時定時器一旦到期,內(nèi)核將產(chǎn)生該信號奔誓。實(shí)時定時器是根據(jù)掛鐘時間進(jìn)行計時的
- SIGBUS:(bus error)表示發(fā)生了某種內(nèi)存訪問錯誤
- SIGCHLD:當(dāng)父進(jìn)程的某一子進(jìn)程終止時(調(diào)用exit()或被信號殺死)斤吐,內(nèi)核將向父進(jìn)程發(fā)送該信號厨喂,當(dāng)父進(jìn)程的某一子進(jìn)程因收到信號而停止或恢復(fù)時,也可能會向父進(jìn)程發(fā)送該信號
- SIGCLD:同SIGCHLD
- SIGCONT:將該信號發(fā)送給已停止的進(jìn)程,進(jìn)程將會恢復(fù)運(yùn)行
- SIGEMT:UNIX系統(tǒng)通常用該信號標(biāo)識一個依賴于實(shí)現(xiàn)的硬件錯誤
- SIGFPE:該信號因特定類型的算術(shù)錯誤而產(chǎn)生,比如除0,后綴FPE是浮點(diǎn)異常的縮寫。
- SIGHUP:當(dāng)終端斷開(掛機(jī))時,將發(fā)送該信號給終端控制進(jìn)程隔嫡。
- SIGILL:執(zhí)行非法的機(jī)器語言指令
- SIFINFO:鍵入Control—T產(chǎn)生SIFINFO信號秸滴,用于獲取前臺進(jìn)程組的狀態(tài)信息
- SIGINT:鍵入Control-C
- SIGIO:利用fcntl()系統(tǒng)調(diào)用内颗,即可與特點(diǎn)類型(終端和套接字)的打開文件描述符發(fā)生I/O事件時產(chǎn)生該信號
- SIGIOT:與SIGABRT同義
- SIGKILL:必殺信號,處理器程序無法將其阻塞
- SIGLOST
- SIGPIPE
- SIGPOLL
- SIGPROF
- SIGPWR:電源故障信號
- SIGQUIT
-
SIGSEGC:這一信號非常常見,當(dāng)應(yīng)用程序?qū)?nèi)存的引用無效時,就會產(chǎn)生該信號。可能出現(xiàn)的情況:
- 要引用的頁不存在,該頁位于堆和棧之間的未映射區(qū)域
- 進(jìn)程試圖更新只讀內(nèi)存
- 進(jìn)程企圖在用戶態(tài)去訪問內(nèi)核的部分內(nèi)存
- SIGSTKFLT
- SIGSTOP:必停信號,處理器程序無法將其阻塞、忽略或捕獲
- SIGSYS:程序發(fā)起的系統(tǒng)調(diào)用有誤
- SIGTERM:終止進(jìn)程的標(biāo)準(zhǔn)信號砌滞,也是kill和killall命令發(fā)送的默認(rèn)信號
- SIGTRAP:用來實(shí)現(xiàn)斷點(diǎn)調(diào)試功能以及strace(1)命令所執(zhí)行的跟蹤系統(tǒng)調(diào)用功能。
- SIGTSTP:作業(yè)控制的停止信號
- SIGTTIN
- SIGTTOU
- SIGUNUSED
- SIGURG
- SIGUSR1:該信號與SIGUSR2信號供程序員自定義使用鹏秋,內(nèi)核絕不會為進(jìn)程產(chǎn)生這些信號百拓。進(jìn)程可以使用這些信號來相互通知事件的發(fā)生蓖捶,或是彼此同步
- SIGVTALRM
- SIGWINCH:終端窗口尺寸發(fā)生變化時
- SIGXCPU:當(dāng)進(jìn)程的CPU時間超出對應(yīng)的資源限制
- SIGXFSZ:如果進(jìn)程視圖增大文件而突破對進(jìn)程文件大小的資源限制
改變信號處置:signal()
void signal(int sig, void (*handler)(int))
信號處理器簡介
信號處理器程序(也稱為信號捕捉器)是當(dāng)指定信號傳遞給進(jìn)程時將會調(diào)用的一個函數(shù),調(diào)用信號處理器程序雁歌,可能會隨時打斷主程序流程,內(nèi)核代表進(jìn)程來調(diào)用處理器程序,當(dāng)處理器返回時,主程序會在處理器打斷的位置恢復(fù)執(zhí)行溉委。
發(fā)送信號:kill()
與shell的kill命令類似,一個進(jìn)程能夠使用kill()系統(tǒng)調(diào)用向另一進(jìn)程發(fā)送信號
int kill(pid_t pid, int sig)