linux系列之:告诉他,他根本不懂kill
文章目錄
- 簡(jiǎn)介
- 使用kill來(lái)殺死進(jìn)程
- kill的深入用法
- 僵尸進(jìn)程和kill
- java thread dump
- 總結(jié)
簡(jiǎn)介
和很多程序員打過(guò)交道,這些程序員可能熟知for遍歷的好幾種寫法,但是卻對(duì)寫出來(lái)的程序部署的環(huán)境一無(wú)所知。我敢打賭,在spring boot出現(xiàn)之后,已經(jīng)很少有程序員知道tomcat到底是怎么運(yùn)行的了。對(duì)于他們來(lái)說(shuō),運(yùn)行一個(gè)jar包就完事了。
工具的先進(jìn)性確實(shí)帶給我們很多便利,也提升了程序員的開(kāi)發(fā)效率,同時(shí)也降低了程序員的進(jìn)入門檻。今天想和大家一起討論一下,linux中的kill命令到底是做什么用的。
可能很很多小伙伴第一次接觸kill命令是同事告訴他,把進(jìn)程kill掉。那么kill真的是用來(lái)殺進(jìn)程的嗎?
使用kill來(lái)殺死進(jìn)程
先來(lái)看一個(gè)kill最基本,也是最常見(jiàn)的應(yīng)用就是殺死進(jìn)程。在殺死進(jìn)程之前,我們需要找到這個(gè)進(jìn)程ID。
一般情況下是使用ps命令找到這個(gè)進(jìn)程ID。加入這個(gè)進(jìn)程ID=54321。
那么接下來(lái)就可以使用kill 54321來(lái)殺死這個(gè)進(jìn)程了。
更資深一點(diǎn)的同學(xué),可能還會(huì)使用kill -9 54321來(lái)強(qiáng)制殺死這個(gè)進(jìn)程。
有沒(méi)有更深入的用法呢?有的,一起來(lái)看看。
kill的深入用法
先看一下kill的命令參數(shù)到底有那些:
kill kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]可以看到kill的參數(shù)是sig,也就是信號(hào)。也就是說(shuō)kill的本質(zhì)是向程序傳遞信號(hào)的。
如果使用 kill -l ,我們可以得到到底kill可以傳遞多少信號(hào):
kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP6) 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總共64個(gè)信號(hào),可能不同的kill版本,信號(hào)有所不同,但是基本上都覆蓋了常用的信號(hào)。
下面是一些常用信號(hào)的含義:
HUP 1 終端斷線 INT 2 中斷(同 Ctrl + C) QUIT 3 退出(同 Ctrl + \) TERM 15 終止 KILL 9 強(qiáng)制終止 CONT 18 繼續(xù)(與STOP相反, fg/bg命令) STOP 19 暫停(同 Ctrl + Z)怎么看kill的版本呢?
/bin/kill --version kill from util-linux 2.23.2如果kill不傳sig,那么將會(huì)傳默認(rèn)的sig=TERM,也就是15。所以上面的kill 54321和 kill -15 54321是等價(jià)的。
一般情況下,我們優(yōu)先使用SIGTERM信號(hào)。這是因?yàn)楫?dāng)程序收到了SIGTERM信號(hào)之后,會(huì)做一些程序的清理操作,或者說(shuō)是優(yōu)雅的關(guān)閉。
如果傳入kill -9 也就是SIGKILL,那么應(yīng)用程序?qū)o(wú)法捕捉這個(gè)信號(hào),從而導(dǎo)致程序強(qiáng)制被關(guān)閉,有可能會(huì)照成一些異常情況,比如數(shù)據(jù)還沒(méi)有保存,數(shù)據(jù)傳輸還沒(méi)有結(jié)束等等。
sig還有一個(gè)特殊值叫做0,如果傳入0的話,那么并不會(huì)發(fā)送實(shí)際的信號(hào),這個(gè)只是做異常檢測(cè)用的。
pid就是process id,可以理解為是進(jìn)程號(hào)。除了進(jìn)程號(hào)之外,還可以傳入一些特殊值,比如:
- 0 表示當(dāng)前進(jìn)程group的所有進(jìn)程
- -1 表示所有PID>1的進(jìn)程
還有一個(gè)特殊的pid=1,這個(gè)pid表示的是初始進(jìn)程init,這個(gè)進(jìn)程是不可被殺死的。
除了PID之外,我們看到kill還可以接受jobspec。job id可以使用jobs命令來(lái)列出。
僵尸進(jìn)程和kill
上面講到了pid=1的初始進(jìn)程是不能被kill的。還有一種不能被kill的進(jìn)程叫做僵尸進(jìn)程。
僵尸進(jìn)程是linux程序中一個(gè)非常獨(dú)特的狀態(tài),它表示的是進(jìn)程已經(jīng)結(jié)束了,但是又還沒(méi)有完全死亡,就像僵尸一樣。
linux中的5大進(jìn)程狀態(tài)分別是:RUNNING:正在運(yùn)行或等待運(yùn)行狀態(tài),UNINTERRUPTABLE:不可中斷阻塞狀態(tài),INTERRUPTABLE:可中斷阻塞狀態(tài),STOPPED:掛起狀態(tài)和ZOMBIE:僵尸狀態(tài)。
那么什么是僵尸進(jìn)程呢?
僵尸進(jìn)程指的是程序在退出之后,該進(jìn)程并不是馬上消失的,而是會(huì)保留一個(gè)被稱為僵尸的數(shù)據(jù)結(jié)構(gòu)。這個(gè)數(shù)據(jù)結(jié)構(gòu)很特殊,因?yàn)槠錄](méi)有內(nèi)存空間,沒(méi)有可執(zhí)行的代碼,當(dāng)然也不可以被調(diào)度。它只是在進(jìn)程列表中占有一個(gè)位置,記錄了該進(jìn)程退出時(shí)候的各種信息。
僵尸進(jìn)程主要是保留進(jìn)程退出的現(xiàn)場(chǎng),供父進(jìn)程或者系統(tǒng)管理員進(jìn)行分析使用的,所以僵尸進(jìn)程是交由父進(jìn)程來(lái)進(jìn)行收集和釋放的。因?yàn)榻┦M(jìn)程已經(jīng)退出了,所以使用kill是沒(méi)有用的,只能等待其父進(jìn)程退出,才能真正的退出。
怎么查看僵尸進(jìn)程呢?最簡(jiǎn)單的方法就是使用top命令:
top - 14:34:38 up 305 days, 4:23, 2 users, load average: 0.20, 0.29, 0.47 Tasks: 93 total, 1 running, 92 sleeping, 0 stopped, 0 zombie %Cpu(s): 2.0 us, 0.7 sy, 0.0 ni, 97.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 1882008 total, 525524 free, 311440 used, 1045044 buff/cache KiB Swap: 0 total, 0 free, 0 used. 1382560 avail Mem上面的輸出,我們可以看到里面有0個(gè)zombie。
java thread dump
kill還有一個(gè)非常有用的地方就是生成java程序的thread dump,將當(dāng)前java程序的線程信息dump出來(lái),可以進(jìn)行一些有用的分析,比如死鎖分析等。
怎么對(duì)java進(jìn)程做thread dump呢?很簡(jiǎn)單使用kill -3 命令即可:
kill -3 <pid>從上面我們的介紹可以指定3代表的信號(hào)是SIGQUIT。這說(shuō)明JVM內(nèi)置了這個(gè)信號(hào)的捕捉,如果接收到了這個(gè)信號(hào),則會(huì)dump當(dāng)前的線程信息。
java thread dump在對(duì)java進(jìn)行線程分析的時(shí)候非常有用。
總結(jié)
本文介紹了kill的深入用法和底層的工作原理,還介紹了kill的幾個(gè)應(yīng)用,希望下次有人再問(wèn)你kill到底是什么的時(shí)候,大家都可以很自豪的告訴他!
本文已收錄于 http://www.flydean.com/01-that-is-kill/
最通俗的解讀,最深刻的干貨,最簡(jiǎn)潔的教程,眾多你不知道的小技巧等你來(lái)發(fā)現(xiàn)!
歡迎關(guān)注我的公眾號(hào):「程序那些事」,懂技術(shù),更懂你!
總結(jié)
以上是生活随笔為你收集整理的linux系列之:告诉他,他根本不懂kill的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 5W字高质量java并发系列详解教程(上
- 下一篇: netty系列之:在netty中处理CO