|   Linux信號簡介  時(shi)間(jian):2017-01-05作者:華清遠見 一、信號及信號來源 信號本質 信(xin)號(hao)是在(zai)軟件(jian)層次(ci)上(shang)對(dui)中(zhong)斷機制(zhi)的(de)(de)一(yi)種模擬,在(zai)原理上(shang),一(yi)個(ge)(ge)進(jin)(jin)(jin)程收到(dao)一(yi)個(ge)(ge)信(xin)號(hao)與(yu)處(chu)理器收到(dao)一(yi)個(ge)(ge)中(zhong)斷請求可以(yi)說是一(yi)樣的(de)(de)。信(xin)號(hao)是異(yi)步的(de)(de),一(yi)個(ge)(ge)進(jin)(jin)(jin)程不必通過任何操(cao)作來等待信(xin)號(hao)的(de)(de)到(dao)達(da),事(shi)實(shi)上(shang),進(jin)(jin)(jin)程也不知道信(xin)號(hao)到(dao)底什么(me)時候到(dao)達(da)。 信(xin)(xin)號(hao)是(shi)進(jin)程間通信(xin)(xin)機制(zhi)中(zhong)唯一的異步通信(xin)(xin)機制(zhi),可以(yi)看作(zuo)是(shi)異步通知(zhi)(zhi),通知(zhi)(zhi)接收信(xin)(xin)號(hao)的進(jin)程有哪(na)些(xie)事情發(fa)生了。信(xin)(xin)號(hao)機制(zhi)經過(guo)POSIX實(shi)時擴展后,功能更加強大(da),除了基本(ben)通知(zhi)(zhi)功能外,還可以(yi)傳遞附加信(xin)(xin)息。 信號來源 信號(hao)事件(jian)的發生有兩個來源:硬件(jian)來源(比(bi)如我(wo)們按下了鍵盤(pan)或者其它硬件(jian)故障);軟件(jian)來源,常用發送(song)信號(hao)的系統函數是kill, raise, alarm和(he)setitimer以及sigqueue函數,軟件(jian)來源還包括一些非(fei)法運算等操作。 二、信號的種類 可(ke)(ke)(ke)以從兩個不同的(de)分類(lei)角(jiao)度對信號(hao)進行分類(lei):(1)可(ke)(ke)(ke)靠性方面:可(ke)(ke)(ke)靠信號(hao)與(yu)(yu)不可(ke)(ke)(ke)靠信號(hao),(2)與(yu)(yu)時間(jian)的(de)關系上:實時信號(hao)與(yu)(yu)非實時信號(hao)。在《Linux環境進程間(jian)通(tong)信(一):管道(dao)(dao)及有名管道(dao)(dao)》的(de)附(fu)1中(zhong)列出了系統所支持的(de)所有信號(hao)。 1、可靠(kao)信號與不可靠(kao)信號 "不可(ke)靠信(xin)號" Linux信(xin)號機(ji)(ji)制(zhi)基本上(shang)是(shi)從Unix系(xi)統中繼(ji)承過來的(de)。早期Unix系(xi)統中的(de)信(xin)號機(ji)(ji)制(zhi)比(bi)較簡(jian)單和原始,后(hou)來在實踐中暴露出一些問題,因此,把那些建立(li)在早期機(ji)(ji)制(zhi)上(shang)的(de)信(xin)號叫做"不可(ke)(ke)靠信(xin)號",信(xin)號值小于SIGRTMIN(Red hat7.2中,SIGRTMIN=32,SIGRTMAX=63)的(de)信(xin)號都是(shi)不可(ke)(ke)靠信(xin)號。這(zhe)就是(shi)"不可(ke)(ke)靠信(xin)號"的(de)來源。它(ta)的(de)主要問題是(shi): · 進程每次處理信(xin)號(hao)后,就(jiu)將對(dui)信(xin)號(hao)的響應(ying)設置為默認動作。在(zai)某些情況下,將導致對(dui)信(xin)號(hao)的錯誤處理;因(yin)此,用戶如(ru)果不希望(wang)這樣的操(cao)作,那么(me)就(jiu)要(yao)在(zai)信(xin)號(hao)處理函(han)數結尾再一次調用signal(),重新安裝(zhuang)該信(xin)號(hao)。 · 信(xin)號可(ke)能(neng)丟失,后面將對此詳細闡(chan)述。 因此,早(zao)期unix下的不可(ke)(ke)靠信(xin)(xin)號(hao)主要(yao)指的是進程可(ke)(ke)能對信(xin)(xin)號(hao)做(zuo)出錯誤的反應以及信(xin)(xin)號(hao)可(ke)(ke)能丟失。 Linux支持(chi)不可(ke)靠(kao)(kao)(kao)信(xin)號(hao)(hao),但(dan)是(shi)(shi)對不可(ke)靠(kao)(kao)(kao)信(xin)號(hao)(hao)機(ji)(ji)制(zhi)做(zuo)了改進(jin):在(zai)調用完信(xin)號(hao)(hao)處理(li)函(han)數后(hou),不必重新調用該(gai)信(xin)號(hao)(hao)的(de)安(an)裝(zhuang)函(han)數(信(xin)號(hao)(hao)安(an)裝(zhuang)函(han)數是(shi)(shi)在(zai)可(ke)靠(kao)(kao)(kao)機(ji)(ji)制(zhi)上的(de)實現(xian))。因此(ci),Linux下(xia)的(de)不可(ke)靠(kao)(kao)(kao)信(xin)號(hao)(hao)問題主要(yao)指(zhi)的(de)是(shi)(shi)信(xin)號(hao)(hao)可(ke)能丟失(shi)。 "可靠(kao)信(xin)號(hao)" 隨著時間的(de)(de)發展,實(shi)(shi)踐(jian)證明了有(you)必要對(dui)(dui)信(xin)(xin)(xin)(xin)號的(de)(de)原始機(ji)制(zhi)加(jia)以(yi)改進(jin)和(he)擴充(chong)。所以(yi),后來(lai)(lai)出(chu)現(xian)的(de)(de)各種Unix版(ban)本(ben)分(fen)別在這(zhe)(zhe)方面進(jin)行(xing)了研(yan)究,力圖實(shi)(shi)現(xian)"可(ke)靠(kao)信(xin)(xin)(xin)(xin)號"。由于(yu)原來(lai)(lai)定義的(de)(de)信(xin)(xin)(xin)(xin)號已有(you)許(xu)多應用,不(bu)好再做(zuo)改動,終(zhong)只(zhi)好又新增(zeng)加(jia)了一些信(xin)(xin)(xin)(xin)號,并在一開始就把它們定義為可(ke)靠(kao)信(xin)(xin)(xin)(xin)號,這(zhe)(zhe)些信(xin)(xin)(xin)(xin)號支持排隊,不(bu)會丟失。同時,信(xin)(xin)(xin)(xin)號的(de)(de)發送和(he)安(an)裝(zhuang)也出(chu)現(xian)了新版(ban)本(ben):信(xin)(xin)(xin)(xin)號發送函(han)數(shu)sigqueue()及信(xin)(xin)(xin)(xin)號安(an)裝(zhuang)函(han)數(shu)sigaction()。POSIX.4對(dui)(dui)可(ke)靠(kao)信(xin)(xin)(xin)(xin)號機(ji)制(zhi)做(zuo)了標準化。但是(shi),POSIX只(zhi)對(dui)(dui)可(ke)靠(kao)信(xin)(xin)(xin)(xin)號機(ji)制(zhi)應具(ju)有(you)的(de)(de)功能以(yi)及信(xin)(xin)(xin)(xin)號機(ji)制(zhi)的(de)(de)對(dui)(dui)外(wai)接口做(zuo)了標準化,對(dui)(dui)信(xin)(xin)(xin)(xin)號機(ji)制(zhi)的(de)(de)實(shi)(shi)現(xian)沒有(you)作具(ju)體的(de)(de)規定。 信(xin)(xin)號(hao)(hao)(hao)值位于SIGRTMIN和SIGRTMAX之間的(de)信(xin)(xin)號(hao)(hao)(hao)都是可靠(kao)信(xin)(xin)號(hao)(hao)(hao),可靠(kao)信(xin)(xin)號(hao)(hao)(hao)克(ke)服了信(xin)(xin)號(hao)(hao)(hao)可能丟失的(de)問題。Linux在支(zhi)持(chi)新版本(ben)的(de)信(xin)(xin)號(hao)(hao)(hao)安裝函數(shu)sigation()以及信(xin)(xin)號(hao)(hao)(hao)發(fa)送函數(shu)sigqueue()的(de)同時,仍(reng)然支(zhi)持(chi)早期的(de)signal()信(xin)(xin)號(hao)(hao)(hao)安裝函數(shu),支(zhi)持(chi)信(xin)(xin)號(hao)(hao)(hao)發(fa)送函數(shu)kill()。 注:不(bu)要有這樣(yang)的(de)(de)誤解:由sigqueue()發(fa)送、sigaction安(an)(an)裝(zhuang)的(de)(de)信(xin)(xin)號(hao)(hao)(hao)就是(shi)可(ke)(ke)靠(kao)(kao)(kao)的(de)(de)。事實上,可(ke)(ke)靠(kao)(kao)(kao)信(xin)(xin)號(hao)(hao)(hao)是(shi)指后來添加的(de)(de)新(xin)信(xin)(xin)號(hao)(hao)(hao)(信(xin)(xin)號(hao)(hao)(hao)值(zhi)位于SIGRTMIN及SIGRTMAX之間);不(bu)可(ke)(ke)靠(kao)(kao)(kao)信(xin)(xin)號(hao)(hao)(hao)是(shi)信(xin)(xin)號(hao)(hao)(hao)值(zhi)小于SIGRTMIN的(de)(de)信(xin)(xin)號(hao)(hao)(hao)。信(xin)(xin)號(hao)(hao)(hao)的(de)(de)可(ke)(ke)靠(kao)(kao)(kao)與不(bu)可(ke)(ke)靠(kao)(kao)(kao)只與信(xin)(xin)號(hao)(hao)(hao)值(zhi)有關,與信(xin)(xin)號(hao)(hao)(hao)的(de)(de)發(fa)送及安(an)(an)裝(zhuang)函數(shu)無關。目前linux中(zhong)的(de)(de)signal()是(shi)通過sigation()函數(shu)實現(xian)的(de)(de),因此(ci),即使通過signal()安(an)(an)裝(zhuang)的(de)(de)信(xin)(xin)號(hao)(hao)(hao),在信(xin)(xin)號(hao)(hao)(hao)處理函數(shu)的(de)(de)結尾也不(bu)必(bi)再調(diao)用一次信(xin)(xin)號(hao)(hao)(hao)安(an)(an)裝(zhuang)函數(shu)。同(tong)時,由signal()安(an)(an)裝(zhuang)的(de)(de)實時信(xin)(xin)號(hao)(hao)(hao)支持排隊,同(tong)樣(yang)不(bu)會丟失。 對于目前(qian)linux的(de)兩個(ge)信(xin)號安(an)裝函(han)數:signal()及(ji)sigaction()來(lai)說,它(ta)們都不(bu)能(neng)把(ba)SIGRTMIN以前(qian)的(de)信(xin)號變成可(ke)靠(kao)(kao)信(xin)號(都不(bu)支持排(pai)隊,仍有可(ke)能(neng)丟失,仍然(ran)是不(bu)可(ke)靠(kao)(kao)信(xin)號),而(er)且(qie)對SIGRTMIN以后的(de)信(xin)號都支持排(pai)隊。這兩個(ge)函(han)數的(de)大區別(bie)在(zai)于,經(jing)過sigaction安(an)裝的(de)信(xin)號都能(neng)傳遞信(xin)息給信(xin)號處(chu)理(li)函(han)數(對所有信(xin)號這一(yi)點都成立),而(er)經(jing)過signal安(an)裝的(de)信(xin)號卻不(bu)能(neng)向信(xin)號處(chu)理(li)函(han)數傳遞信(xin)息。對于信(xin)號發送函(han)數來(lai)說也是一(yi)樣的(de)。 三、信號的安裝(設置信號關聯動作) 如果進(jin)程要(yao)(yao)處(chu)理某一信(xin)號(hao)(hao),那(nei)么就要(yao)(yao)在進(jin)程中安(an)裝該信(xin)號(hao)(hao)。安(an)裝信(xin)號(hao)(hao)主要(yao)(yao)用來確(que)定信(xin)號(hao)(hao)值(zhi)及進(jin)程針(zhen)對該信(xin)號(hao)(hao)值(zhi)的動作之間(jian)的映射關(guan)系,即(ji)進(jin)程將(jiang)要(yao)(yao)處(chu)理哪個信(xin)號(hao)(hao);該信(xin)號(hao)(hao)被傳遞給進(jin)程時,將(jiang)執行何種操(cao)作。 linux主要(yao)(yao)有兩(liang)個(ge)函(han)數實現信號(hao)(hao)的安(an)裝:signal()、sigaction()。其中signal()在(zai)可靠信號(hao)(hao)系統調(diao)用(yong)(yong)的基礎上實現,是(shi)庫函(han)數。它只(zhi)有兩(liang)個(ge)參(can)(can)數,不(bu)支(zhi)持(chi)(chi)信號(hao)(hao)傳遞信息,主要(yao)(yao)是(shi)用(yong)(yong)于前32種非實時信號(hao)(hao)的安(an)裝;而sigaction()是(shi)較新的函(han)數(由兩(liang)個(ge)系統調(diao)用(yong)(yong)實現:sys_signal以及sys_rt_sigaction),有三個(ge)參(can)(can)數,支(zhi)持(chi)(chi)信號(hao)(hao)傳遞信息,主要(yao)(yao)用(yong)(yong)來(lai)與(yu) sigqueue()系統調(diao)用(yong)(yong)配合使用(yong)(yong),當然,sigaction()同樣(yang)支(zhi)持(chi)(chi)非實時信號(hao)(hao)的安(an)裝。sigaction()優于signal()主要(yao)(yao)體現在(zai)支(zhi)持(chi)(chi)信號(hao)(hao)帶有參(can)(can)數。 
	1、signal() 如(ru)果該函數(shu)原(yuan)型不容易理解的話(hua),可以(yi)參考下面的分(fen)解方(fang)式來(lai)理解: 
	typedef void (*sighandler_t)(int); 第一個(ge)參(can)數(shu)指定信(xin)號的值(zhi),第二個(ge)參(can)數(shu)指定針對(dui)前面(mian)信(xin)號值(zhi)的處(chu)理,可以(yi)忽略該信(xin)號(參(can)數(shu)設(she)為SIG_IGN);可以(yi)采用(yong)系統默認方(fang)(fang)式處(chu)理信(xin)號(參(can)數(shu)設(she)為SIG_DFL);也可以(yi)自己實現處(chu)理方(fang)(fang)式(參(can)數(shu)指定一個(ge)函數(shu)地址(zhi))。 如果signal()調用成(cheng)功,返回后一次為安裝信(xin)號(hao)signum而(er)調用signal()時的handler值;失敗則返回SIG_ERR。 
	2、sigaction() sigaction函(han)數用(yong)于改變進(jin)程接收(shou)到(dao)特(te)定(ding)信(xin)(xin)(xin)號(hao)后的(de)(de)(de)(de)(de)行為(wei)。該函(han)數的(de)(de)(de)(de)(de)第(di)一個(ge)參(can)數為(wei)信(xin)(xin)(xin)號(hao)的(de)(de)(de)(de)(de)值,可(ke)(ke)以(yi)為(wei)除SIGKILL及SIGSTOP外(wai)的(de)(de)(de)(de)(de)任(ren)何一個(ge)特(te)定(ding)有效(xiao)的(de)(de)(de)(de)(de)信(xin)(xin)(xin)號(hao)(為(wei)這兩個(ge)信(xin)(xin)(xin)號(hao)定(ding)義自己的(de)(de)(de)(de)(de)處理函(han)數,將導致信(xin)(xin)(xin)號(hao)安裝(zhuang)錯(cuo)誤)。第(di)二個(ge)參(can)數是指(zhi)(zhi)向結構(gou)sigaction的(de)(de)(de)(de)(de)一個(ge)實例的(de)(de)(de)(de)(de)指(zhi)(zhi)針,在結構(gou)sigaction的(de)(de)(de)(de)(de)實例中(zhong),指(zhi)(zhi)定(ding)了對(dui)特(te)定(ding)信(xin)(xin)(xin)號(hao)的(de)(de)(de)(de)(de)處理,可(ke)(ke)以(yi)為(wei)空,進(jin)程會以(yi)缺省方(fang)式對(dui)信(xin)(xin)(xin)號(hao)處理;第(di)三(san)個(ge)參(can)數oldact指(zhi)(zhi)向的(de)(de)(de)(de)(de)對(dui)象用(yong)來保存原來對(dui)相應信(xin)(xin)(xin)號(hao)的(de)(de)(de)(de)(de)處理,可(ke)(ke)指(zhi)(zhi)定(ding)oldact為(wei)NULL。如果把(ba)第(di)二、第(di)三(san)個(ge)參(can)數都設為(wei)NULL,那么該函(han)數可(ke)(ke)用(yong)于檢查(cha)信(xin)(xin)(xin)號(hao)的(de)(de)(de)(de)(de)有效(xiao)性。 第(di)二個(ge)參數為重要,其中包含了(le)對指定信號(hao)的處理、信號(hao)所傳遞的信息、信號(hao)處理函數執行過程中應屏蔽掉哪(na)些函數等等。 
 相關資訊 發表評論 
 |