linux進程間通信信號
時間:2018-08-27 來(lai)源:未知(zhi)
信 號 :
同步通信:按照某種順(shun)序依(yi)次(ci)做(zuo)事情。
異步通(tong)信:接收到(dao)(dao)某(mou)個信號,去執行(xing)某(mou)個操(cao)作,然后再接著(zhu)做之前的事情(qing)阻塞(sai):沒有等(deng)(deng)到(dao)(dao)結果,不做其他(ta)事情(qing),一直等(deng)(deng)待
非阻塞:沒有等到(dao)結果,直(zhi)接(jie)返回。信(xin)號(hao)是唯一一種異步通(tong)信(xin)的方式
信(xin)號(hao)是信(xin)息的(de)載體,Linux/UNIX 環(huan)境下,古(gu)老、經(jing)典(dian)的(de)通信(xin)方式(shi), 現下依然是主(zhu)要的(de)通信(xin)手段(duan)。Unix早期版本(ben)就提供了信(xin)號(hao)機制,但不可(ke)靠,信(xin)號(hao)可(ke)能丟失(shi)。Berkeley 和
AT&T都對信號模型做了更改,增加了可(ke)靠信號機制。但彼此(ci)不兼容。POSIX.1對可(ke)靠信號例程進(jin)行了標準化。
一個(ge)完整的(de)信(xin)號生命周(zhou)期(qi)可(ke)以分為(wei)3個(ge)重要階段,這3個(ge)階段由4個(ge)重要事(shi)件來刻畫
$信號產生
$信號(hao)在進(jin)程中注冊
$信號(hao)在進程中注銷
$執行(xing)信號處理函(han)數(shu)
相(xiang)鄰兩個(ge)事(shi)件的(de)時間(jian)間(jian)隔構成信號生命周(zhou)期的(de)一個(ge)階(jie)段
信(xin)號處理有多(duo)種方式(shi),一(yi)般是由內核完成(cheng)的(de),當(dang)然也可以(yi)有用戶進程完成(cheng)不可靠信(xin)號的(de)處理過程(信(xin)號值(zhi)在32號之(zhi)前)
$發(fa)現該信號已經在進程中注冊(ce),則忽略該信號
$故若前(qian)一個信號(hao)(hao)還未注(zhu)銷又(you)產(chan)生(sheng)了相同的信號(hao)(hao)就會產(chan)生(sheng)信號(hao)(hao)丟(diu)失(shi)可靠信號(hao)(hao)的處理過(guo)程(cheng)(信號(hao)(hao)值在32號(hao)(hao)之后)
$發現信號不(bu)管該信號是否已經在進(jin)程中注(zhu)冊,都會被再(zai)注(zhu)冊所有可靠(kao)信號都支持(chi)排(pai)隊(dui),而不(bu)可靠(kao)信號則(ze)都不(bu)支持(chi)排(pai)隊(dui)

信(xin)號的機制:
A給B發送信(xin)號(hao),B收(shou)到信(xin)號(hao)之前執行(xing)(xing)自(zi)己的代碼(ma),收(shou)到信(xin)號(hao)后,不管(guan)執行(xing)(xing)到程序的什
么位置,都要暫停(ting)運(yun)行(xing),去處理信號(hao)(hao),處理完畢再繼續執行(xing)。與硬件中(zhong)斷(duan)(duan)類似——異步模 式。但信號(hao)(hao)是軟件層(ceng)面上實現(xian)的中(zhong)斷(duan)(duan),早期常被稱(cheng)為“軟中(zhong)斷(duan)(duan)”。
信(xin)號(hao)(hao)的特質:由于信(xin)號(hao)(hao)是(shi)通過軟件(jian)方(fang)法實現,其實現手段導(dao)致信(xin)號(hao)(hao)有很強(qiang)的延時性。 但對于用(yong)戶來說,這個延遲時間非常短,不(bu)易(yi)察(cha)覺。
每個進程收到(dao)的所有信號,都(dou)是由內核負責發送(song)的,內核處理。
與信號相關的事(shi)件和(he)狀態
產生信號:
1. 按鍵產生,如:Ctrl+c、Ctrl+z、Ctrl+\
2. 系統調用(yong)產生(sheng),如:kill、raise、abort
3. 軟件(jian)條件(jian)產生,如:定時器alarm
4. 硬件異常產生,如:非法訪(fang)問內存(段錯誤)、除0(浮(fu)點數例外)、內存對(dui)齊出錯
(總線錯誤)
5. 命令產生,如:kill命令遞達:遞送并且到達進程。
未決:產生和遞達之間的狀(zhuang)態。主要由(you)于(yu)阻(zu)塞(屏蔽)導致(zhi)該狀(zhuang)態。 信號的處理方(fang)式:
1. 執行默認(ren)動作,由Linux規定的默認(ren)操作。
2. 忽略(lve)(丟棄);SIGKILL及SIGSTOP不可(ke)被忽略(lve)。
3. 捕捉(zhuo)(調用(yong)戶(hu)處理函(han)數(shu))
Linux內核的(de)進(jin)程控(kong)制塊PCB是(shi)一(yi)個結構體,task_struct, 除了包含(han)進(jin)程id,狀態,工作目錄,用戶id,組id,文件描述符表,還包含(han)了信(xin)(xin)號(hao)相關的(de)信(xin)(xin)息,主要指阻(zu)塞信(xin)(xin)號(hao)集和未決(jue)信(xin)(xin)號(hao)集。
阻塞信(xin)(xin)(xin)號(hao)集(ji)(信(xin)(xin)(xin)號(hao)屏蔽字): 將某些信(xin)(xin)(xin)號(hao)加(jia)入(ru)集(ji)合,對(dui)他們設置屏蔽,當(dang)屏蔽x信(xin)(xin)(xin)號(hao)后(hou)(hou)(hou),再收到該信(xin)(xin)(xin)號(hao),該信(xin)(xin)(xin)號(hao)的處理將推(tui)后(hou)(hou)(hou)(解除屏蔽后(hou)(hou)(hou))
未決信號集(ji):
1. 信(xin)號(hao)產生,未決信(xin)號(hao)集(ji)中描(miao)述該信(xin)號(hao)的位立(li)刻翻轉為1,表(biao)信(xin)號(hao)處于未決狀態。當信(xin)號(hao)被處理(li)對應位翻轉回為0。這一時刻往(wang)往(wang)非(fei)常短(duan)暫。
2. 信(xin)號(hao)產生后由于(yu)某些原因(主(zhu)要(yao)是(shi)阻塞)不(bu)能抵達。這類信(xin)號(hao)的集合稱之(zhi)為未(wei)決(jue)信(xin) 號(hao)集。在(zai)屏蔽(bi)解除前,信(xin)號(hao)一直處于(yu)未(wei)決(jue)狀態。
查看(kan)所(suo)有的信號: kill -l
信號四要素:
與變量三要(yao)素(su)類(lei)似的,每(mei)個(ge)信號(hao)也有其必(bi)備4要(yao)素(su),分(fen)別是:
1. 編號 2. 名稱(cheng) 3. 事(shi)件 4. 默認處(chu)理(li)動作
不同(tong)的(de)操作系統定義了(le)不同(tong)的(de)系統信號。因此有些信號出(chu)現(xian)(xian)在(zai)(zai)Unix系統內,也出(chu)現(xian)(xian)在(zai)(zai)
Linux中,而有的信號出(chu)現在FreeBSD或(huo)Mac OS中卻(que)沒有出(chu)現在Linux下。這里我們只研究
Linux系統中的信(xin)號。默認動作:
Term:終止(zhi)進程
Ign: 忽略信號 (默認即(ji)時對該種信號忽略操作)
Core:終(zhong)止進程(cheng),生成Core文(wen)件。(查驗進程(cheng)死亡原因, 用于gdb調試(shi)) Stop:停止(暫(zan)停)進程(cheng)
Cont:繼續運行進程
注意從man 7 signal幫助文檔中可(ke)看到 : The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
這里特別強(qiang)調了(le)9) SIGKILL 和(he)19) SIGSTOP信號(hao),不允許忽略和(he)捕(bu)捉(zhuo),只能(neng)執行(xing)默認動作。甚至不能(neng)將其(qi)設置為(wei)阻塞。
1) SIGHUP: 當用(yong)戶退出shell時(shi),由(you)該shell啟(qi)動(dong)的所有進程(cheng)將收(shou)到這個(ge)信號,默(mo)認動(dong)作(zuo)為終止進程(cheng)
2) SIGINT:當用(yong)戶按下(xia)了組合(he)鍵時,用(yong)戶終端(duan)向正在(zai)運(yun)行中的由該終端(duan)啟(qi)動的程序發出此信號。默認(ren)動作為終止(zhi)進程。
3) SIGQUIT:當(dang)用戶按下組(zu)合鍵時產生(sheng)該(gai)(gai)信(xin)(xin)號,用戶終(zhong)端(duan)向正在(zai)運行中的(de)(de)由該(gai)(gai)終(zhong)端(duan)啟動的(de)(de)程序(xu)發出(chu)些信(xin)(xin)號。默認動作為(wei)終(zhong)止進程.
4) SIGILL:CPU檢測到某進(jin)程(cheng)執行了非法指令(ling)。默(mo)認動(dong)作(zuo)為(wei)終止進(jin)程(cheng)并產生core文件
5) SIGTRAP:該信號由斷點(dian)指令(ling)(ling)或其他 trap指令(ling)(ling)產生。默認動(dong)作為(wei)終止里程 并產生core文件。
6) SIGABRT: 調用abort函(han)數時產(chan)生該(gai)信號。默認動作(zuo)為終(zhong)止進(jin)程并產(chan)生core文件。
7) SIGBUS:非法訪問內(nei)存(cun)地(di)址(zhi),包括內(nei)存(cun)對齊出(chu)錯(cuo),默認動作為(wei)終止進程(cheng)并產(chan)生core文件(jian)。
8) SIGFPE:在發生致命(ming)的(de)運算(suan)錯誤時發出。不僅包(bao)括浮點運算(suan)錯誤,還包(bao)括溢出及除數為(wei)(wei)0等所有的(de)算(suan)法(fa)錯誤。默(mo)認動作為(wei)(wei)終止進程并產(chan)生core文件。
9) SIGKILL:無條件終止進(jin)(jin)程。本信(xin)號不(bu)能被忽略,處理和(he)阻塞(sai)。默認動作為終止進(jin)(jin)程。它向(xiang)系統(tong)管(guan)理員提供了可(ke)以殺死(si)任何進(jin)(jin)程的方法。
10) SIGUSE1:用(yong)戶(hu)定義 的信號。即(ji)程序員可以在(zai)程序中(zhong)定義并使用(yong)該信號。默認動作(zuo)為終(zhong)止進(jin)程。
11) SIGSEGV:指示進(jin)程進(jin)行了無效內存訪問。默(mo)認動作為終止(zhi)進(jin)程并(bing)產生core文件。
12) SIGUSR2:另外一個用(yong)戶自定(ding)義(yi)信號,程(cheng)序(xu)員可(ke)以在程(cheng)序(xu)中定(ding)義(yi)并使用(yong)該信號。默認(ren)動作為終止(zhi)進程(cheng)。
13) SIGPIPE:Broken pipe向(xiang)一(yi)個沒有讀端的管道寫數據。默認動(dong)作為終止進程(cheng)。
14) SIGALRM: 定時器超時,超時的時間 由(you)系統調用(yong)alarm設置。默認動作為終止(zhi)進(jin)程。
15) SIGTERM:程序結束信(xin)號,與SIGKILL不(bu)同的(de)是,該信(xin)號可(ke)以被阻(zu)塞和終止。
通常用(yong)來要示(shi)程序正常退出。執(zhi)行shell命令Kill時,缺省產生這個信號。默(mo)認動作為終止進程。
16) SIGSTKFLT:Linux早期版本(ben)出現的信號,現仍保留(liu)向后兼容(rong)。默認動作(zuo)為終(zhong)止進程。
17) SIGCHLD:子進程結(jie)束時,父進程會收到這個(ge)信號。默認(ren)動作為忽略這個(ge)信號。
18) SIGCONT:如果進(jin)程已停止(zhi),則使(shi)其繼(ji)續運行。默認動作(zuo)為繼(ji)續/忽(hu)略。
19) SIGSTOP:停止進程的執行(xing)。信號不能被忽略,處理和阻塞(sai)。默認動作為暫(zan)停進程。
20) SIGTSTP:停止(zhi)終(zhong)端交互進(jin)程(cheng)的(de)運行。按下組合鍵時(shi)發(fa)出這(zhe)個信號。默認動作為暫停進(jin)程(cheng)。
21) SIGTTIN:后(hou)臺(tai)進(jin)程讀終端(duan)控制臺(tai)。默認動作為暫停進(jin)程。
22) SIGTTOU: 該信號類似于SIGTTIN,在后臺進(jin)程要向(xiang)終端輸出數據時(shi)發生。默(mo)認動作(zuo)為(wei)暫停進(jin)程。
23) SIGURG:套接字上有緊(jin)急數據時(shi),向(xiang)當(dang)前正在運行(xing)的進程發出些信號,報告有緊(jin)急數據到(dao)達。如網(wang)絡帶外數據到(dao)達,默認動作為忽略該(gai)信號。
24) SIGXCPU:進(jin)程執行時間超(chao)過了分配給(gei)該進(jin)程的(de)CPU時間 ,系(xi)統產生該信號并發送給(gei)該進(jin)程。默(mo)認(ren)動作為終止進(jin)程。
25) SIGXFSZ:超過文件(jian)的(de)最大長度設置(zhi)。默認動作為終止進程。
26) SIGVTALRM:虛擬時鐘超時時產(chan)生該信(xin)號。類似于SIGALRM,但是該信(xin)號只計(ji)算該進程占用
CPU的使(shi)用時間。默(mo)認動(dong)作為終(zhong)止(zhi)進程。
27) SGIPROF:類似于(yu)SIGVTALRM,它不公(gong)包括該進(jin)程(cheng)(cheng)占用(yong)CPU時(shi)間還包括執(zhi)行系(xi)統(tong)調用(yong)時(shi)間。默認(ren)動作(zuo)為終(zhong)止進(jin)程(cheng)(cheng)。
28) SIGWINCH:窗口變化大(da)小(xiao)時發(fa)出。默(mo)認動作為忽略該信(xin)號。
29) SIGIO:此信(xin)號向進程指示發出了一個異步IO事件。默認動作為忽略。
30) SIGPWR:關機(ji)。默(mo)認動作為(wei)終止進程。
31) SIGSYS:無效的系統調用。默認動作為終(zhong)止(zhi)進(jin)程并產生(sheng)core文(wen)件。
34) SIGRTMIN ~ (64) SIGRTMAX:LINUX的(de)實(shi)時(shi)信(xin)號(hao)(hao),它(ta)們(men)沒有固定(ding)的(de)含義(可以由用戶自(zi)定(ding)義)。所有的(de)實(shi)時(shi)信(xin)號(hao)(hao)的(de)默認動作(zuo)都為終止進程。
終端按鍵產生信號
Ctrl + c → 2) SIGINT(終止/中斷) "INT" Interrupt
Ctrl + z → 20) SIGTSTP(暫(zan)停/停止) "T" ----Terminal 終端。 Ctrl + \ → 3) SIGQUIT(退出)
硬(ying)件(jian)異常產生信號(hao)
除0操作 → 8) SIGFPE (浮點數例(li)外(wai)) "F" -----float 浮點數。非法訪(fang)問內存 → 11) SIGSEGV (段錯誤)
總線錯誤 → 7) SIGBUS