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

          第一個(gè)Blog,記錄哈哈的生活

          常用鏈接

          留言簿(16)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          收藏夾

          Java links

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          @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信號(hào)

          UNIX中進(jìn)程組織結(jié)構(gòu)為 session (會(huì)話(huà))包含一個(gè)前臺(tái)進(jìn)程組及一個(gè)或多個(gè)后臺(tái)進(jìn)程組,一個(gè)進(jìn)程組包含多個(gè)進(jìn)程。一個(gè)session可能會(huì)有一個(gè)session首進(jìn)程,而一個(gè)session首進(jìn)程可能會(huì)有一個(gè)控制終端。一個(gè)進(jìn)程組可能會(huì)有一個(gè)進(jìn)程組首進(jìn)程。進(jìn)程組首進(jìn)程的進(jìn)程ID與該進(jìn)程組ID相等。這兒是可能會(huì)有,在一定情況之下是沒(méi)有的。與終端交互的進(jìn)程是前臺(tái)進(jìn)程,否則便是后臺(tái)進(jìn)程。
          SIGHUP會(huì)在以下3種情況下被發(fā)送給相應(yīng)的進(jìn)程:
          1、終端關(guān)閉時(shí),該信號(hào)被發(fā)送到session首進(jìn)程以及作為job提交的進(jìn)程(即用 & 符號(hào)提交的進(jìn)程)
          2、session首進(jìn)程退出時(shí),該信號(hào)被發(fā)送到該session中的前臺(tái)進(jìn)程組中的每一個(gè)進(jìn)程
          3、若父進(jìn)程退出導(dǎo)致進(jìn)程組成為孤兒進(jìn)程組,且該進(jìn)程組中有進(jìn)程處于停止?fàn)顟B(tài)(收到SIGSTOP或SIGTSTP信號(hào)),該信號(hào)會(huì)被發(fā)送到該進(jìn)程組中的每一個(gè)進(jìn)程。
          統(tǒng)對(duì)SIGHUP信號(hào)的默認(rèn)處理是止收到信號(hào)的進(jìn)程。所以若程序中沒(méi)有捕捉信號(hào),當(dāng)收到信號(hào)時(shí)進(jìn)程就會(huì)退出。
          下面觀察幾種因終端關(guān)閉導(dǎo)致進(jìn)程退出的情況,在這兒進(jìn)程退出是因?yàn)槭盏搅薙IGHUP信號(hào)。login shell是session首進(jìn)程。
          首先寫(xiě)一個(gè)測(cè)試程序,代碼如下:
          #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信號(hào)后打印一條信息,pause()使程序暫停。
          編譯后的執(zhí)行文件為sigtest。
          1、命 令:sigtest front > tt.txt
             操 作:關(guān)閉終端
             結(jié) 果:tt.txt文件的內(nèi)容為front : sighup received
             原 因: sigtest是前臺(tái)進(jìn)程,終端關(guān)閉后,根據(jù)上面提到的第1種情況,login shell作為session首進(jìn)程,會(huì)收到SIGHUP信號(hào)然后退出。根據(jù)第2種情況,sigtest作為前臺(tái)進(jìn)程,會(huì)收到login shell發(fā)出的SIGHUP信號(hào)。
          2、命 令:sigtest back > tt.txt &
               操 作:關(guān)閉終端
                結(jié) 果:tt.txt文件的內(nèi)容為 back : sighup received
                原 因: sigtest是提交的job,根據(jù)上面提到的第1種情況,sigtest會(huì)收到SIGHUP信號(hào)。
          3、命 令:寫(xiě)一個(gè)shell,內(nèi)容為[sigtest &],然后執(zhí)行該shell
                操 作:關(guān)閉終端
                結(jié) 果:ps -ef | grep sigtest 會(huì)看到該進(jìn)程還在,tt文件為空
                原 因: 執(zhí)行該shell時(shí),sigtest作為job提交,然后該shell退出,致使sigtest變成了孤兒進(jìn)程,不再是當(dāng)前session的job了,因此sigtest即不是session首進(jìn)程也不是job,不會(huì)收到SIGHUP。同時(shí)孤兒進(jìn)程屬于后臺(tái)進(jìn)程,因此login shell退出后不會(huì)發(fā)送SIGHUP給sigtest,因?yàn)樗粚⒃撔盘?hào)發(fā)送給前臺(tái)進(jìn)程。第3條說(shuō)過(guò)若進(jìn)程組變成孤兒進(jìn)程組的時(shí)候,若有進(jìn)程處于停止?fàn)顟B(tài),也會(huì)收到SIGHUP信號(hào),但sigtest沒(méi)有處于停止?fàn)顟B(tài),所以不會(huì)收到SIGHUP信號(hào)。
          4、命 令:nohup sigtest > tt
                操 作:關(guān)閉終端
                結(jié) 果:tt文件為空
                原 因: nohup可以防止進(jìn)程收到SIGHUP信號(hào)
          至此,我們就清楚了何種情況下終端關(guān)閉后進(jìn)程會(huì)退出,何種情況下不會(huì)退出。


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

          2.SIGCHLD信號(hào)

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

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

          2.SIGTERM信號(hào)

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

          SIGTERM 信號(hào)的處理函數(shù),常見(jiàn)的是用來(lái)清理、退出;或者程序可以忽略這個(gè)信號(hào),以防誤殺。
                  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信號(hào)列表
          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

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

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

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

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

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

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

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

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

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

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

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

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

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

          10) SIGUSR1
          留給用戶(hù)使用

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

          12) SIGUSR2
          留給用戶(hù)使用

          13) SIGPIPE
          管道破裂。這個(gè)信號(hào)通常在進(jìn)程間通信產(chǎn)生,比如采用FIFO(管道)通信的兩個(gè)進(jìn)程,讀管道沒(méi)打開(kāi)或者意外終止就往管道寫(xiě),寫(xiě)進(jìn)程會(huì)收到SIGPIPE信號(hào)。此外用Socket通信的兩個(gè)進(jìn)程,寫(xiě)進(jìn)程在寫(xiě)Socket的時(shí)候,讀進(jìn)程已經(jīng)終止。

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

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

          17) SIGCHLD
          子進(jìn)程結(jié)束時(shí), 父進(jìn)程會(huì)收到這個(gè)信號(hào)。

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

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

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

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

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

          22) SIGTTOU
          類(lèi)似于SIGTTIN, 但在寫(xiě)終端(或修改終端模式)時(shí)收到.

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

          24) SIGXCPU
          超過(guò)CPU時(shí)間資源限制. 這個(gè)限制可以由getrlimit/setrlimit來(lái)讀取/改變。

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

          26) SIGVTALRM
          虛擬時(shí)鐘信號(hào). 類(lèi)似于SIGALRM, 但是計(jì)算的是該進(jìn)程占用的CPU時(shí)間.

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

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

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

          30) SIGPWR
          Power failure

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

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

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

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

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 台东市| 青田县| 内黄县| 汝城县| 太仓市| 海丰县| 阜平县| 寿宁县| 尼勒克县| 聊城市| 夏邑县| 宁乡县| 北碚区| 中江县| 崇信县| 汤原县| 绩溪县| 连江县| 宁国市| 缙云县| 盖州市| 祥云县| 宜章县| 河西区| 措美县| 洞头县| 腾冲县| 宁德市| 健康| 鹤山市| 磴口县| 西畴县| 手游| 石门县| 綦江县| 平泉县| 梅河口市| 修武县| 邵东县| 康定县| 云阳县|