Linux信號機制與信號處理

信號(signal)是Linux進程間通信的一種機制理朋,全稱為軟中斷信號拉岁,也被稱為軟中斷航揉。信號本質(zhì)上是在軟件層次上對硬件中斷機制的一種模擬。

與其他進程間通信方式(例如管道邑飒、共享內(nèi)存等)相比循签,信號所能傳遞的信息比較粗糙,只是一個整數(shù)疙咸。但正是由于傳遞的信息量少县匠,信號也便于管理和使用,可以用于系統(tǒng)管理相關(guān)的任務撒轮,例如通知進程終結(jié)乞旦、中止或者恢復等。

每種信號用一個整型常量宏表示题山,以SIG開頭兰粉,比如SIGCHLD、SIGINT等顶瞳,它們在系統(tǒng)頭文件中定義玖姑。

信號由內(nèi)核(kernel)管理,產(chǎn)生方式多種多樣:

可以由內(nèi)核自身產(chǎn)生慨菱,比如出現(xiàn)硬件錯誤焰络、內(nèi)存讀取錯誤,分母為0的除法等符喝,內(nèi)核需要通知相應進程闪彼。

也可以由其他進程產(chǎn)生并發(fā)送給內(nèi)核,再由內(nèi)核傳遞給目標進程洲劣。

信號傳遞的過程:

內(nèi)核中針對每一個進程都有一個表來保存信號备蚓。

當內(nèi)核需要將信號傳遞給某個進程時课蔬,就在該進程對應的表中寫入信號囱稽,這樣就生成了信號。

當該進程由用戶態(tài)陷入內(nèi)核態(tài)二跋,再次切換到用戶態(tài)之前战惊,會查看表中的信號。如果有信號扎即,進程就會首先執(zhí)行信號對應的操作吞获,此時叫做執(zhí)行信號况凉。

從生成信號到將信號傳遞給對應進程這段時間,信號處于等待狀態(tài)各拷。

我們可以編寫代碼刁绒,讓進程阻塞(block)某些信號,也就是讓這些信號始終處于等待的狀態(tài)烤黍,直到進程取消阻塞(unblock)或者忽略信號知市。

信號種類

下表列出了一些常見信號:

信號名稱數(shù)字表示說明

SIGHUP 1 終端掛起或控制進程終止。當用戶退出Shell時速蕊,由該進程啟動的所有進程都會收到這個信號嫂丙,默認動作為終止進程。

SIGINT 2 鍵盤中斷规哲。當用戶按下組合鍵時跟啤,用戶終端向正在運行中的由該終端啟動的程序發(fā)出此信號。默認動作為終止進程唉锌。

SIGQUIT 3 鍵盤退出鍵被按下隅肥。當用戶按下或組合鍵時,用戶終端向正在運行中的由該終端啟動的程序發(fā)出此信號袄简。默認動作為退出程序武福。

SIGFPE 8 發(fā)生致命的運算錯誤時發(fā)出。不僅包括浮點運算錯誤痘番,還包括溢出及除數(shù)為0等所有的算法錯誤捉片。默認動作為終止進程并產(chǎn)生core文件。

SIGKILL 9 無條件終止進程汞舱。進程接收到該信號會立即終止伍纫,不進行清理和暫存工作。該信號不能被忽略昂芜、處理和阻塞莹规,它向系統(tǒng)管理員提供了可以殺死任何進程的方法。

SIGALRM 14 定時器超時泌神,默認動作為終止進程良漱。

SIGTERM 15 程序結(jié)束信號,可以由?kill 命令產(chǎn)生欢际。與SIGKILL不同的是母市,SIGTERM 信號可以被阻塞和終止,以便程序在退出前可以保存工作或清理臨時文件等损趋。

通過 kill -l 命令可以查看系統(tǒng)支持的所有信號:

$ kill -l

1) SIGHUP? ? ? 2) SIGINT? ? ? 3) SIGQUIT? ? ? 4) SIGILL

5) SIGTRAP? ? ? 6) SIGABRT? ? ? 7) SIGBUS? ? ? 8) SIGFPE

9) SIGKILL? ? 10) SIGUSR1? ? 11) SIGSEGV? ? 12) SIGUSR2

13) SIGPIPE? ? 14) SIGALRM? ? 15) SIGTERM? ? 16) SIGSTKFLT

17) SIGCHLD? ? 18) SIGCONT? ? 19) SIGSTOP? ? 20) SIGTSTP

21) SIGTTIN? ? 22) SIGTTOU? ? 23) SIGURG? ? ? 24) SIGXCPU

25) SIGXFSZ? ? 26) SIGVTALRM? 27) SIGPROF? ? 28) SIGWINCH

29) SIGIO? ? ? 30) SIGPWR? ? ? 31) SIGSYS? ? ? 34) SIGRTMIN

35) SIGRTMIN+1? 36) SIGRTMIN+2? 37) SIGRTMIN+3? 38) SIGRTMIN+4

39) SIGRTMIN+5? 40) SIGRTMIN+6? 41) SIGRTMIN+7? 42) SIGRTMIN+8

43) SIGRTMIN+9? 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12

47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14

51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10

55) SIGRTMAX-9? 56) SIGRTMAX-8? 57) SIGRTMAX-7? 58) SIGRTMAX-6

59) SIGRTMAX-5? 60) SIGRTMAX-4? 61) SIGRTMAX-3? 62) SIGRTMAX-2

63) SIGRTMAX-1? 64) SIGRTMAX

上面僅是一個演示患久,不同的Linux發(fā)行版支持的信號可能不同。

每種信號都會有一個默認動作。默認動作就是腳本或程序接收到該信號所做出的默認操作蒋失。常見的默認動作有終止進程返帕、退出程序、忽略信號篙挽、重啟暫停的進程等荆萤,上表中也對部分默認動作進行了說明。

發(fā)送信號

有多種方式可以向程序或腳本發(fā)送信號铣卡,例如按下組合鍵會發(fā)送SIGINT信號观腊,終止當前進程。

還可以通過 kill 命令發(fā)送信號算行,語法為:

$ kill -signal pid

signal為要發(fā)送的信號梧油,可以是信號名稱或數(shù)字;pid為接收信號的進程ID州邢。例如:

$ kill -1 1001

將SIGHUP信號發(fā)送給進程ID為1001的程序儡陨,程序會終止執(zhí)行。

又如量淌,強制殺死ID為1001的進程:

$ kill -9 1001

捕獲信號

通常情況下骗村,直接終止進程并不是我們所希望的。例如呀枢,按下胚股,進程被立即終止,不會清理創(chuàng)建的臨時文件裙秋,帶來系統(tǒng)垃圾琅拌,也不會保存正在進行的工作,導致需要重做摘刑。

可以通過編程來捕獲這些信號进宝,當終止信號出現(xiàn)時,可以先進行清場和保存處理枷恕,再退出程序党晋。

用戶程序可以通過C/C++等代碼捕獲信號,這將在Linux C編程中進行講解徐块,這里僅介紹如果通過Linux命令捕獲信號未玻。

通過 trap 命令就可以捕獲信號,語法為:

$ trap commands signals

commands為Linux系統(tǒng)命令或用戶自定義命令胡控;signals為要捕獲的信號扳剿,可以為信號名稱或數(shù)字。

捕獲到信號后铜犬,可以有三種處理:

執(zhí)行一段腳本來做一些處理工作舞终,例如清理臨時文件轻庆;

接受(恢復)信號的默認操作癣猾;

忽略當前信號敛劝。

1) 清理臨時文件

腳本捕獲到終止信號后一個常見的動作就是清理臨時文件。例如:

$ trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2

當用戶按下后纷宇,腳本先清理臨時文件?work1

和dataout

再退出夸盟。

注意:exit 命令是必須的,否則腳本捕獲到信號后會繼續(xù)執(zhí)行而不是退出像捶。

修改上面的腳本上陕,使接收到?SIGHUP 時進行同樣的操作:

$ trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2

幾點注意:

如果執(zhí)行多個命令,需要將命令用引號包圍拓春;

只有腳本執(zhí)行到 trap 命令時才會捕獲信號释簿;

再次接收到信號時還會執(zhí)行同樣的操作。

上面的腳本硼莽,執(zhí)行到 trap 命令時就會替換?WORKDIR 和 $$ 的值庶溶。如果希望接收到 SIGHUP 或 SIGINT 信號時再替換其值,那么可以將命令放在單引號內(nèi)懂鸵,例如:

$ trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2

2) 忽略信號

如果 trap 命令的 commands 為空偏螺,將會忽略接收到的信號,即不做任何處理匆光,也不執(zhí)行默認動作套像。例如:

$ trap '' 2

也可以同時忽略多個信號:

$ trap '' 1 2 3 15

注意:必須被引號包圍,不能寫成下面的形式:

$ trap? 2

3) 恢復默認動作

如果希望改變信號的默認動作后再次恢復默認動作终息,那么省略 trap 命令的 commands 即可夺巩,例如:

$ trap 1 2

將恢復SIGHUP 和 SIGINT 信號的默認動作。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末周崭,一起剝皮案震驚了整個濱河市劲够,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌休傍,老刑警劉巖征绎,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異磨取,居然都是意外死亡人柿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門忙厌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凫岖,“玉大人,你說我怎么就攤上這事逢净「绶牛” “怎么了歼指?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長甥雕。 經(jīng)常有香客問我踩身,道長,這世上最難降的妖魔是什么社露? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任挟阻,我火速辦了婚禮,結(jié)果婚禮上峭弟,老公的妹妹穿的比我還像新娘附鸽。我一直安慰自己,他們只是感情好瞒瘸,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布坷备。 她就那樣靜靜地躺著,像睡著了一般情臭。 火紅的嫁衣襯著肌膚如雪省撑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天谎柄,我揣著相機與錄音丁侄,去河邊找鬼。 笑死朝巫,一個胖子當著我的面吹牛鸿摇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播劈猿,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼拙吉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了揪荣?” 一聲冷哼從身側(cè)響起筷黔,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仗颈,沒想到半個月后佛舱,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡挨决,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年请祖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脖祈。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡肆捕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盖高,到底是詐尸還是另有隱情慎陵,我是刑警寧澤眼虱,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站席纽,受9級特大地震影響捏悬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胆筒,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一邮破、第九天 我趴在偏房一處隱蔽的房頂上張望诈豌。 院中可真熱鬧仆救,春花似錦、人聲如沸矫渔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庙洼。三九已至顿痪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間油够,已是汗流浹背蚁袭。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留石咬,地道東北人揩悄。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像鬼悠,于是被迫代替她去往敵國和親删性。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容