隨筆 - 175  文章 - 202  trackbacks - 0
          <2011年8月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          第一個Blog,記錄哈哈的生活

          常用鏈接

          留言簿(16)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          Java links

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          @import url(http://www.aygfsteel.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

          http://en.wikipedia.org/wiki/Category:Unix_signals

          1.SIGHUP信號

          UNIX中進(jìn)程組織結(jié)構(gòu)為 session (會話)包含一個前臺進(jìn)程組及一個或多個后臺進(jìn)程組,一個進(jìn)程組包含多個進(jìn)程。一個session可能會有一個session首進(jìn)程,而一個session首進(jìn)程可能會有一個控制終端。一個進(jìn)程組可能會有一個進(jìn)程組首進(jìn)程。進(jìn)程組首進(jìn)程的進(jìn)程ID與該進(jìn)程組ID相等。這兒是可能會有,在一定情況之下是沒有的。與終端交互的進(jìn)程是前臺進(jìn)程,否則便是后臺進(jìn)程。
          SIGHUP會在以下3種情況下被發(fā)送給相應(yīng)的進(jìn)程:
          1、終端關(guān)閉時,該信號被發(fā)送到session首進(jìn)程以及作為job提交的進(jìn)程(即用 & 符號提交的進(jìn)程)
          2、session首進(jìn)程退出時,該信號被發(fā)送到該session中的前臺進(jìn)程組中的每一個進(jìn)程
          3、若父進(jìn)程退出導(dǎo)致進(jìn)程組成為孤兒進(jìn)程組,且該進(jìn)程組中有進(jìn)程處于停止?fàn)顟B(tài)(收到SIGSTOP或SIGTSTP信號),該信號會被發(fā)送到該進(jìn)程組中的每一個進(jìn)程。
          統(tǒng)對SIGHUP信號的默認(rèn)處理是止收到信號的進(jìn)程。所以若程序中沒有捕捉信號,當(dāng)收到信號進(jìn)程就會退出。
          下面觀察幾種因終端關(guān)閉導(dǎo)致進(jìn)程退出的情況,在這兒進(jìn)程退出是因?yàn)槭盏搅薙IGHUP信號。login shell是session首進(jìn)程。
          首先寫一個測試程序,代碼如下:
          #include <stdio.h>
          #include 
          <signal.h>
          char **args;
          void exithandle(int
           sig)
          {
                  printf(
          "%s : sighup received ",args[1
          ]);
          }

          int main(int argc,char **argv)
          {
                  args 
          =
           argv;
                  signal(SIGHUP,exithandle);
                  pause();
                 
          return 0
          ;
          }
          程序中捕捉SIGHUP信號后打印一條信息,pause()使程序暫停。
          編譯后的執(zhí)行文件為sigtest。
          1、命 令:sigtest front > tt.txt
             操 作:關(guān)閉終端
             結(jié) 果:tt.txt文件的內(nèi)容為front : sighup received
             原 因: sigtest是前臺進(jìn)程,終端關(guān)閉后,根據(jù)上面提到的第1種情況,login shell作為session首進(jìn)程,會收到SIGHUP信號然后退出。根據(jù)第2種情況,sigtest作為前臺進(jìn)程,會收到login shell發(fā)出的SIGHUP信號。
          2、命 令:sigtest back > tt.txt &
               操 作:關(guān)閉終端
                結(jié) 果:tt.txt文件的內(nèi)容為 back : sighup received
                原 因: sigtest是提交的job,根據(jù)上面提到的第1種情況,sigtest會收到SIGHUP信號。
          3、命 令:寫一個shell,內(nèi)容為[sigtest &],然后執(zhí)行該shell
                操 作:關(guān)閉終端
                結(jié) 果:ps -ef | grep sigtest 會看到該進(jìn)程還在,tt文件為空
                原 因: 執(zhí)行該shell時,sigtest作為job提交,然后該shell退出,致使sigtest變成了孤兒進(jìn)程,不再是當(dāng)前session的job了,因此sigtest即不是session首進(jìn)程也不是job,不會收到SIGHUP。同時孤兒進(jìn)程屬于后臺進(jìn)程,因此login shell退出后不會發(fā)送SIGHUP給sigtest,因?yàn)樗粚⒃撔盘柊l(fā)送給前臺進(jìn)程。第3條說過若進(jìn)程組變成孤兒進(jìn)程組的時候,若有進(jìn)程處于停止?fàn)顟B(tài),也會收到SIGHUP信號,但sigtest沒有處于停止?fàn)顟B(tài),所以不會收到SIGHUP信號。
          4、命 令:nohup sigtest > tt
                操 作:關(guān)閉終端
                結(jié) 果:tt文件為空
                原 因: nohup可以防止進(jìn)程收到SIGHUP信號
          至此,我們就清楚了何種情況下終端關(guān)閉后進(jìn)程會退出,何種情況下不會退出。


          要想終端關(guān)閉后進(jìn)程不退出有以下幾種方法,均為通過shell的方式:
          1、編寫shell,內(nèi)容如下
                 trap "" SIGHUP #該句的作用是屏蔽SIGHUP信號,trap可以屏蔽很多信號
                sigtest
          2、nohup sigtest 可以直接在命令行執(zhí)行,
                 若想做完該操作后繼續(xù)別的操作,可以 nohup sigtest &
          3、編寫shell,內(nèi)容如下
                 sigtest &
                 其實(shí)任何將進(jìn)程變?yōu)楣聝哼M(jìn)程的方式都可以,包括fork后父進(jìn)程馬上退出。

          2.SIGCHLD信號

                 子進(jìn)程死后,會發(fā)送SIGCHLD信號給父進(jìn)程。

                  一個進(jìn)程在調(diào)用exit命令結(jié)束自己的生命的時候,其實(shí)它并沒有真正的被銷毀,而是留下一個稱為僵尸進(jìn)程(Zombie)的數(shù)據(jù)結(jié)構(gòu)(系統(tǒng)調(diào)用exit,它的作用是使進(jìn)程退出,但也僅僅限于將一個正常的進(jìn)程變成一個僵尸進(jìn)程,并不能將其完全銷毀)。在Linux進(jìn)程的狀態(tài)中,僵尸進(jìn)程 是非常特殊的一種,它已經(jīng)放棄了幾乎所有內(nèi)存空間,沒有任何可執(zhí)行代碼,也不能被調(diào)度,僅僅在進(jìn)程列表中保留一個位置,記載該進(jìn)程的退出狀態(tài)等信息供其他進(jìn)程收集,除此之外,僵尸進(jìn)程不再占有任何內(nèi)存空間。它需要它的父進(jìn)程來為它收尸,如果他的父進(jìn)程沒安裝SIGCHLD信號處理函數(shù)調(diào)用wait或waitpid()等待子進(jìn)程結(jié)束,又沒有顯式忽略該信號,那么它就一直保持僵尸狀態(tài),如果這時父進(jìn)程結(jié)束了,那么init進(jìn)程自動會接手這個子進(jìn)程,為它收尸,它還是能被清除的。但是如果如果父進(jìn)程是一個循環(huán),不會結(jié)束,那么子進(jìn)程就會一直保持僵尸狀態(tài),這就是為什么系統(tǒng)中有時會有很多的僵尸進(jìn)程。

          2.SIGTERM信號

          kill() 可以發(fā) SIGTERM 過去;kill 命令默認(rèn)也使用 SIGTERM 信號。

          SIGTERM 信號的處理函數(shù),常見的是用來清理、退出;或者程序可以忽略這個信號,以防誤殺。
                  SIGTERM is the default signal sent to a process by the kill or killall commands. It causes the termination of a process, but unlike the SIGKILLsignal, it can be caught and interpreted (or ignored) by the process. Therefore, SIGTERM is more akin to asking a process to terminate nicely, allowing cleanup and closure of files. For this reason, on many Unix systems during shutdown, init issues SIGTERM to all processes that are not essential to powering off, waits a few seconds, and then issues SIGKILL to forcibly terminate other processes to allow the computer to halt.




          linux kill信號列表
          2009-04-13 17:00
          $ 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

          列表中,編號為1 ~ 31的信號為傳統(tǒng)UNIX支持的信號,是不可靠信號(非實(shí)時的),編號為32 ~ 63的信號是后來擴(kuò)充的,稱做可靠信號(實(shí)時信號)。不可靠信號和可靠信號的區(qū)別在于前者不支持排隊(duì),可能會造成信號丟失,而后者不會。

          下面我們對編號小于SIGRTMIN的信號進(jìn)行討論。

          1) SIGHUP
          本信號在用戶終端連接(正常或非正常)結(jié)束時發(fā)出, 通常是在終端的控制進(jìn)程結(jié)束時, 通知同一session內(nèi)的各個作業(yè), 這時它們與控制終端不再關(guān)聯(lián)。

          登錄Linux時,系統(tǒng)會分配給登錄用戶一個終端(Session)。在這個終端運(yùn)行的所有程序,包括前臺進(jìn)程組和后臺進(jìn)程組,一般都屬于這個 Session。當(dāng)用戶退出Linux登錄時,前臺進(jìn)程組和后臺有對終端輸出的進(jìn)程將會收到SIGHUP信號。這個信號的默認(rèn)操作為終止進(jìn)程,因此前臺進(jìn) 程組和后臺有終端輸出的進(jìn)程就會中止。不過可以捕獲這個信號,比如wget能捕獲SIGHUP信號,并忽略它,這樣就算退出了Linux登錄,wget也 能繼續(xù)下載。

          此外,對于與終端脫離關(guān)系的守護(hù)進(jìn)程,這個信號用于通知它重新讀取配置文件。

          2) SIGINT
          程序終止(interrupt)信號, 在用戶鍵入INTR字符(通常是Ctrl-C)時發(fā)出,用于通知前臺進(jìn)程組終止進(jìn)程。

          3) SIGQUIT
          和SIGINT類似, 但由QUIT字符(通常是Ctrl-\)來控制. 進(jìn)程在因收到SIGQUIT退出時會產(chǎn)生core文件, 在這個意義上類似于一個程序錯誤信號。

          4) SIGILL
          執(zhí)行了非法指令. 通常是因?yàn)榭蓤?zhí)行文件本身出現(xiàn)錯誤, 或者試圖執(zhí)行數(shù)據(jù)段. 堆棧溢出時也有可能產(chǎn)生這個信號。

          5) SIGTRAP
          由斷點(diǎn)指令或其它trap指令產(chǎn)生. 由debugger使用。

          6) SIGABRT
          調(diào)用abort函數(shù)生成的信號。

          7) SIGBUS
          非法地址, 包括內(nèi)存地址對齊(alignment)出錯。比如訪問一個四個字長的整數(shù), 但其地址不是4的倍數(shù)。它與SIGSEGV的區(qū)別在于后者是由于對合法存儲地址的非法訪問觸發(fā)的(如訪問不屬于自己存儲空間或只讀存儲空間)。

          8) SIGFPE
          在發(fā)生致命的算術(shù)運(yùn)算錯誤時發(fā)出. 不僅包括浮點(diǎn)運(yùn)算錯誤, 還包括溢出及除數(shù)為0等其它所有的算術(shù)的錯誤。

          9) SIGKILL
          用來立即結(jié)束程序的運(yùn)行. 本信號不能被阻塞、處理和忽略。如果管理員發(fā)現(xiàn)某個進(jìn)程終止不了,可嘗試發(fā)送這個信號。

          10) SIGUSR1
          留給用戶使用

          11) SIGSEGV
          試圖訪問未分配給自己的內(nèi)存, 或試圖往沒有寫權(quán)限的內(nèi)存地址寫數(shù)據(jù).

          12) SIGUSR2
          留給用戶使用

          13) SIGPIPE
          管道破裂。這個信號通常在進(jìn)程間通信產(chǎn)生,比如采用FIFO(管道)通信的兩個進(jìn)程,讀管道沒打開或者意外終止就往管道寫,寫進(jìn)程會收到SIGPIPE信號。此外用Socket通信的兩個進(jìn)程,寫進(jìn)程在寫Socket的時候,讀進(jìn)程已經(jīng)終止。

          14) SIGALRM
          時鐘定時信號, 計(jì)算的是實(shí)際的時間或時鐘時間. alarm函數(shù)使用該信號.

          15) SIGTERM
          程序結(jié)束(terminate)信號, 與SIGKILL不同的是該信號可以被阻塞和處理。通常用來要求程序自己正常退出,shell命令kill缺省產(chǎn)生這個信號。如果進(jìn)程終止不了,我們才會嘗試SIGKILL。

          17) SIGCHLD
          子進(jìn)程結(jié)束時, 父進(jìn)程會收到這個信號。

          如果父進(jìn)程沒有處理這個信號,也沒有等待(wait)子進(jìn)程,子進(jìn)程雖然終止,但是還會在內(nèi)核進(jìn)程表中占有表項(xiàng),這時的子進(jìn)程稱為僵尸進(jìn)程。這種情 況我們應(yīng)該避免(父進(jìn)程或者忽略SIGCHILD信號,或者捕捉它,或者wait它派生的子進(jìn)程,或者父進(jìn)程先終止,這時子進(jìn)程的終止自動由init進(jìn)程來接管)。

          18) SIGCONT
          讓一個停止(stopped)的進(jìn)程繼續(xù)執(zhí)行. 本信號不能被阻塞. 可以用一個handler來讓程序在由stopped狀態(tài)變?yōu)槔^續(xù)執(zhí)行時完成特定的工作. 例如, 重新顯示提示符...

          19) SIGSTOP
          停止(stopped)進(jìn)程的執(zhí)行. 注意它和terminate以及interrupt的區(qū)別:該進(jìn)程還未結(jié)束, 只是暫停執(zhí)行. 本信號不能被阻塞, 處理或忽略.

          20) SIGTSTP
          停止進(jìn)程的運(yùn)行, 但該信號可以被處理和忽略. 用戶鍵入SUSP字符時(通常是Ctrl-Z)發(fā)出這個信號

          21) SIGTTIN
          當(dāng)后臺作業(yè)要從用戶終端讀數(shù)據(jù)時, 該作業(yè)中的所有進(jìn)程會收到SIGTTIN信號. 缺省時這些進(jìn)程會停止執(zhí)行.

          22) SIGTTOU
          類似于SIGTTIN, 但在寫終端(或修改終端模式)時收到.

          23) SIGURG
          有"緊急"數(shù)據(jù)或out-of-band數(shù)據(jù)到達(dá)socket時產(chǎn)生.

          24) SIGXCPU
          超過CPU時間資源限制. 這個限制可以由getrlimit/setrlimit來讀取/改變。

          25) SIGXFSZ
          當(dāng)進(jìn)程企圖擴(kuò)大文件以至于超過文件大小資源限制。

          26) SIGVTALRM
          虛擬時鐘信號. 類似于SIGALRM, 但是計(jì)算的是該進(jìn)程占用的CPU時間.

          27) SIGPROF
          類似于SIGALRM/SIGVTALRM, 但包括該進(jìn)程用的CPU時間以及系統(tǒng)調(diào)用的時間.

          28) SIGWINCH
          窗口大小改變時發(fā)出.

          29) SIGIO
          文件描述符準(zhǔn)備就緒, 可以開始進(jìn)行輸入/輸出操作.

          30) SIGPWR
          Power failure

          31) SIGSYS
          非法的系統(tǒng)調(diào)用。

          在以上列出的信號中,程序不可捕獲、阻塞或忽略的信號有:SIGKILL,SIGSTOP
          不能恢復(fù)至默認(rèn)動作的信號有:SIGILL,SIGTRAP
          默認(rèn)會導(dǎo)致進(jìn)程流產(chǎn)的信號有:SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGIOT,SIGQUIT,SIGSEGV,SIGTRAP,SIGXCPU,SIGXFSZ
          默認(rèn)會導(dǎo)致進(jìn)程退出的信號有:SIGALRM,SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,SIGSYS,SIGTERM,SIGUSR1,SIGUSR2,SIGVTALRM
          默認(rèn)會導(dǎo)致進(jìn)程停止的信號有:SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU
          默認(rèn)進(jìn)程忽略的信號有:SIGCHLD,SIGPWR,SIGURG,SIGWINCH

          此外,SIGIO在SVR4是退出,在4.3BSD中是忽略;SIGCONT在進(jìn)程掛起時是繼續(xù),否則是忽略,不能被阻塞。

          posted on 2011-08-16 11:55 哈哈的日子 閱讀(792) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 新平| 五家渠市| 从化市| 双柏县| 惠来县| 莱西市| 昌江| 久治县| 黎平县| 铁岭县| 运城市| 阳高县| 石首市| 正镶白旗| 霍州市| 保康县| 习水县| 千阳县| 黄大仙区| 遵义市| 大足县| 甘泉县| 财经| 会理县| 胶州市| 宁武县| 定结县| 玛曲县| 横山县| 宁远县| 七台河市| 阿合奇县| 黔东| 吴忠市| 安仁县| 西城区| 博罗县| 津南区| 长沙县| 工布江达县| 三门县|