kill -9 linux 用法,【Linux學習筆記】kill及kill -9的用法及如何實現進程的優雅退出...

本篇筆記主要說明兩個問題:1)如何在shell中終止一個后台進程;2)一個后台服務進程如何實現優雅退出

1. kill與signals

我們這里所說的kill是指作為shell command的那個kill(相對地,linux系統中還有個叫做kill的system call, man 2 kill可查看其功能及用法),shell終端中輸入man kill可以看到,kill的作用是向某個指定的進程或進程組發送指定信號,從而結束該進程/進程組。-s選項可以指定要發送的具體信號,如果沒有指定,則默認發送SIGTERM信號至指定進程/進程組,若進程沒有捕獲該信號的邏輯,則SIGTERM的作用是終止進程。

kill支持發送的信號列表可以通過kill -l查看,而這些信號的具體含義可以通過man 7 signal查看。在我的機器上,man 7 signal輸出的POSIX標准信號如下所示(kill支持的信號還有POSIX沒有定義的非標准信號,這里沒有摘出,感興趣的同學可以通過man查看)。

Signal Value Action Comment

-------------------------------------------------------------------------

SIGHUP 1 Term Hangup detected on controlling terminal

or death of controlling process

SIGINT 2 Term Interrupt from keyboard

SIGQUIT 3 Core Quit from keyboard

SIGILL 4 Core Illegal Instruction

SIGABRT 6 Core Abort signal from abort(3)

SIGFPE 8 Core Floating point exception

SIGKILL 9 Term Kill signal

SIGSEGV 11 Core Invalid memory reference

SIGPIPE 13 Term Broken pipe: write to pipe with no readers

SIGALRM 14 Term Timer signal from alarm(2)

SIGTERM 15 Term Termination signal

SIGUSR1 30,10,16 Term User-defined signal 1

SIGUSR2 31,12,17 Term User-defined signal 2

SIGCHLD 20,17,18 Ign Child stopped or terminated

SIGCONT 19,18,25 Continue if stopped

SIGSTOP 17,19,23 Stop Stop process

SIGTSTP 18,20,24 Stop Stop typed at tty

SIGTTIN 21,21,26 Stop tty input for background process

SIGTTOU 22,22,27 Stop tty output for background process

上面的輸出結果中:

第1列為信號名;

第2列為對應的信號值,需要注意的是,有些信號名對應着3個信號值,這是因為這些信號值與平台相關,將man手冊中對3個信號值的說明摘出如下,the first one is usually valid for alpha and sparc, the middle one for i386, ppc and sh, and the last one for mips.

第3列為操作系統收到信號后的動作,Term表明默認動作為終止進程,Ign表明默認動作為忽略該信號,Core表明默認動作為終止進程同時輸出core dump,Stop表明默認動作為停止進程。

第4列為對信號作用的注釋性說明,淺顯易懂,這里不再贅述。

需要特別說明的是,SIGKILL和SIGSTOP這兩個信號既不能被應用程序捕獲,也不能被操作系統阻塞或忽略。

2. kill pid與kill -9 pid的區別

kill pid的作用是向進程號為pid的進程發送SIGTERM(這是kill默認發送的信號),該信號是一個結束進程的信號且可以被應用程序捕獲。若應用程序沒有捕獲並響應該信號的邏輯代碼,則該信號的默認動作是kill掉進程。這是終止指定進程的推薦做法。

kill -9 pid則是向進程號為pid的進程發送SIGKILL(該信號的編號為9),從本文上面的說明可知,SIGKILL既不能被應用程序捕獲,也不能被阻塞或忽略,其動作是立即結束指定進程。通俗地說,應用程序根本無法“感知”SIGKILL信號,它在完全無准備的情況下,就被收到SIGKILL信號的操作系統給干掉了,顯然,在這種“暴力”情況下,應用程序完全沒有釋放當前占用資源的機會。事實上,SIGKILL信號是直接發給init進程的,它收到該信號后,負責終止pid指定的進程。關於linux init進程的說明,可以參考這里或這里。在某些情況下(如進程已經hang死,無法響應正常信號),就可以使用kill -9來結束進程。

若通過kill結束的進程是一個創建過子進程的父進程,則其子進程就會成為孤兒進程(Orphan Process),這種情況下,子進程的退出狀態就不能再被應用進程捕獲(因為作為父進程的應用程序已經不存在了),不過應該不會對整個linux系統產生什么不利影響。

3. 應用程序如何優雅退出

Linux Server端的應用程序經常會長時間運行,在運行過程中,可能申請了很多系統資源,也可能保存了很多狀態,在這些場景下,我們希望進程在退出前,可以釋放資源或將當前狀態dump到磁盤上或打印一些重要的日志,也就是希望進程優雅退出(exit gracefully)。

從上面的介紹不難看出,優雅退出可以通過捕獲SIGTERM來實現。具體來講,通常只需要兩步動作:

1)注冊SIGTERM信號的處理函數並在處理函數中做一些進程退出的准備。信號處理函數的注冊可以通過signal()或sigaction()來實現,其中,推薦使用后者來實現信號響應函數的設置。信號處理函數的邏輯越簡單越好,通常的做法是在該函數中設置一個bool型的flag變量以表明進程收到了SIGTERM信號,准備退出。

2)在主進程的main()中,通過類似於while(!bQuit)的邏輯來檢測那個flag變量,一旦bQuit在signal handler function中被置為true,則主進程退出while()循環,接下來就是一些釋放資源或dump進程當前狀態或記錄日志的動作,完成這些后,主進程退出。

關於進程通過捕獲SIGTERM實現優雅退出的示例,可以參考這里(需翻牆)或這里或者這里。

關於Linux中信號處理方法的詳細說明,強烈推薦閱讀 Signal handling in Linux這篇資料 ,講解的非常詳細。

【參考資料】

============= EOF ===========

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值