linux系列之:告诉他,他根本不懂kill

2021年09月15日 阅读数:2
这篇文章主要向大家介绍linux系列之:告诉他,他根本不懂kill,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

简介

和不少程序员打过交道,这些程序员可能熟知for遍历的好几种写法,可是却对写出来的程序部署的环境一无所知。我敢打赌,在spring boot出现以后,已经不多有程序员知道tomcat究竟是怎么运行的了。对于他们来讲,运行一个jar包就完事了。java

工具的先进性确实带给咱们不少便利,也提高了程序员的开发效率,同时也下降了程序员的进入门槛。今天想和你们一块儿讨论一下,linux中的kill命令究竟是作什么用的。linux

可能很不少小伙伴第一次接触kill命令是同事告诉他,把进程kill掉。那么kill真的是用来杀进程的吗?程序员

使用kill来杀死进程

先来看一个kill最基本,也是最多见的应用就是杀死进程。在杀死进程以前,咱们须要找到这个进程ID。spring

通常状况下是使用ps命令找到这个进程ID。加入这个进程ID=54321。tomcat

那么接下来就可使用kill 54321来杀死这个进程了。数据结构

更资深一点的同窗,可能还会使用kill -9 54321来强制杀死这个进程。工具

有没有更深刻的用法呢?有的,一块儿来看看。线程

kill的深刻用法

先看一下kill的命令参数到底有那些:code

kill 
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]

能够看到kill的参数是sig,也就是信号。也就是说kill的本质是向程序传递信号的。教程

若是使用 kill -l ,咱们能够获得到底kill能够传递多少信号:

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

总共64个信号,可能不一样的kill版本,信号有所不一样,可是基本上都覆盖了经常使用的信号。

下面是一些经常使用信号的含义:

HUP     1    终端断线
INT       2    中断(同 Ctrl + C)
QUIT    3    退出(同 Ctrl + \)
TERM    15    终止
KILL      9    强制终止
CONT   18    继续(与STOP相反, fg/bg命令)
STOP    19    暂停(同 Ctrl + Z)

怎么看kill的版本呢?

/bin/kill --version
kill from util-linux 2.23.2

若是kill不传sig,那么将会传默认的sig=TERM,也就是15。因此上面的kill 54321和 kill -15 54321是等价的。

通常状况下,咱们优先使用SIGTERM信号。这是由于当程序收到了SIGTERM信号以后,会作一些程序的清理操做,或者说是优雅的关闭。

若是传入kill -9 也就是SIGKILL,那么应用程序将没法捕捉这个信号,从而致使程序强制被关闭,有可能会照成一些异常状况,好比数据尚未保存,数据传输尚未结束等等。

sig还有一个特殊值叫作0,若是传入0的话,那么并不会发送实际的信号,这个只是作异常检测用的。

pid就是process id,能够理解为是进程号。除了进程号以外,还能够传入一些特殊值,好比:

  • 0 表示当前进程group的全部进程
  • -1 表示全部PID>1的进程

还有一个特殊的pid=1,这个pid表示的是初始进程init,这个进程是不可被杀死的。

除了PID以外,咱们看到kill还能够接受jobspec。job id可使用jobs命令来列出。

僵尸进程和kill

上面讲到了pid=1的初始进程是不能被kill的。还有一种不能被kill的进程叫作僵尸进程。

僵尸进程是linux程序中一个很是独特的状态,它表示的是进程已经结束了,可是又尚未彻底死亡,就像僵尸同样。

linux中的5大进程状态分别是:RUNNING:正在运行或等待运行状态,UNINTERRUPTABLE:不可中断阻塞状态,INTERRUPTABLE:可中断阻塞状态,STOPPED:挂起状态和ZOMBIE:僵尸状态。

那么什么是僵尸进程呢?

僵尸进程指的是程序在退出以后,该进程并非立刻消失的,而是会保留一个被称为僵尸的数据结构。这个数据结构很特殊,由于其没有内存空间,没有可执行的代码,固然也不能够被调度。它只是在进程列表中占有一个位置,记录了该进程退出时候的各类信息。

僵尸进程主要是保留进程退出的现场,供父进程或者系统管理员进行分析使用的,因此僵尸进程是交由父进程来进行收集和释放的。由于僵尸进程已经退出了,因此使用kill是没有用的,只能等待其父进程退出,才能真正的退出。

怎么查看僵尸进程呢?最简单的方法就是使用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个zombie。

java thread dump

kill还有一个很是有用的地方就是生成java程序的thread dump,将当前java程序的线程信息dump出来,能够进行一些有用的分析,好比死锁分析等。

怎么对java进程作thread dump呢?很简单使用kill -3 命令便可:

kill -3 <pid>

从上面咱们的介绍能够指定3表明的信号是SIGQUIT。这说明JVM内置了这个信号的捕捉,若是接收到了这个信号,则会dump当前的线程信息。

java thread dump在对java进行线程分析的时候很是有用。

总结

本文介绍了kill的深刻用法和底层的工做原理,还介绍了kill的几个应用,但愿下次有人再问你kill究竟是什么的时候,你们均可以很自豪的告诉他!

本文已收录于 http://www.flydean.com/01-that-is-kill/

最通俗的解读,最深入的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注个人公众号:「程序那些事」,懂技术,更懂你!