写点什么

【Linux 技术专题】「夯实基本功系列」带你一同学习和实践操作 Linux 服务器必学的 Shell 指令(深入 Kill 指令探索)

作者:洛神灬殇
  • 2024-01-26
    江苏
  • 本文字数:4209 字

    阅读完需:约 14 分钟

【Linux技术专题】「夯实基本功系列」带你一同学习和实践操作Linux服务器必学的Shell指令(深入Kill指令探索)

Kill 指令探索

许多程序员对程序部署环境了解甚少,特别是在 Spring Boot 出现后,对 Tomcat 的底层运行原理的了解几乎变得罕见。对于他们而言,简单地运行一个 JAR 包就完成了部署工作。


工具的进步确实为我们带来了许多便利,提升了程序员的开发效率,也降低了他们的门槛。今天,我想和大家一起探讨一下 Linux 中的 kill 命令的作用是什么。


很多人初次接触 kill 命令可能是从同事那里听说可以用它来终止进程。但你知道吗,kill 命令真的是专门用来"杀死"进程的吗?

你眼中的 Kill 指令

让我们来看看我们工作中最常见的 kill 命令的用法——杀死进程,首先,我们需要找到要操作的进程 ID,通常可以使用 ps 命令来查找。



  1. 我们找到了进程 ID 为 54321。

  2. 使用 kill 命令将其终止,命令为:kill 54321。

  3. 对于更有经验的开发者,可能会使用 kill -9 54321 来强制终止进程。

Kill 的深入用法

除了常见的用法,kill 命令还有一些更深入的用法和选项,让我们一起来了解一下。

kill 的命令参数

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


kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
复制代码


从官方的指令介绍可以看出 kill 的参数是 sig,也就是信号,因此,kill 命令的本质是向进程发送信号。参数中的"sig"代表信号,它指定了要发送给目标进程的具体信号类型。

kill 的底层原理

通过使用 kill 命令,我们可以向进程发送各种不同的信号,以达到不同的目的。例如,使用 kill 命令发送 SIGTERM 信号可以请求进程正常退出。而使用其他信号如 SIGINT、SIGHUP 和 SIGSTOP 等,可以实现中断进程、重新加载配置文件或暂停进程执行等不同的操作。


因此,可以看到 kill 命令的参数实际上是指定要发送的信号类型,通过发送适当的信号,可以对进程进行控制和操作。这也是 kill 命令的主要功能和本质。

kill 的信号类型

如果使用kill -l ,我们可以得到到底 kill 可以传递多少信号,总共 64 个信号,可能不同的 kill 版本,信号有所不同,但是基本上都覆盖了常用的信号。


 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR111) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+338) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+843) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+1348) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-1253) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-758) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-263) SIGRTMAX-1  64) SIGRTMAX
复制代码


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


  • HUP (SIGHUP): 终端断线信号。当终端连接断开时发送给进程。通常用于通知进程终端断开,并可能触发相应的处理。

  • INT (SIGINT): 中断信号,与按下 Ctrl + C 相同。用户用于终止正在执行的进程。进程可以捕获该信号并执行相应的中断处理操作。

  • QUIT (SIGQUIT): 退出信号,与按下 Ctrl + \ 相同。类似于 SIGINT,但生成一个核心转储文件以供调试使用。通常用于中止进程并生成核心转储。

  • TERM (SIGTERM): 终止信号。请求进程正常退出的信号。进程可以捕获该信号并执行清理操作,以便安全地退出。

  • KILL (SIGKILL): 强制终止信号。立即终止进程,不能被捕获或忽略。应该谨慎使用,仅作为最后手段。

  • CONT (SIGCONT): 继续信号。用于从暂停状态恢复进程执行。通常与 SIGSTOP 结合使用,以恢复之前被暂停的进程。

  • STOP (SIGSTOP): 暂停信号,与按下 Ctrl + Z 相同。用于暂停进程的执行。进程收到该信号后将被挂起,直到收到继续信号 (SIGCONT) 为止。

Kill 的版本如何查看

/bin/kill --versionkill from util-linux xx.xx.xx
复制代码


如果在使用 kill 命令时不指定信号(SIG),则默认传递的信号是 SIGTERM(终止信号),其信号编号为 15。因此,kill 54321 和 kill -15 54321 是等价的两种写法。


注意:sig 还有一个特殊值叫做 0,如果传入 0 的话,那么并不会发送实际的信号,这个只是做异常检测用的

优雅关闭和强制关闭

**优雅关闭:**一般情况下,我们优先使用 SIGTERM 信号。这是因为当程序收到了 SIGTERM 信号之后,会做一些程序的清理操作,或者说是优雅的关闭。


**强制关闭:**如果传入kill -9 也就是 SIGKILL,那么应用程序将无法捕捉这个信号,从而导致程序强制被关闭,有可能会照成一些异常情况,比如数据还没有保存,数据传输还没有结束等等。

Kill 的进程号分析

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


初始进程 init

除了 0 和-1 之外,还有一个特殊的进程 ID(1),进程 ID 为 1 的进程是初始进程 init。


在 UNIX 和类 UNIX 系统中,init 是用户级最早启动的进程,它是系统启动的第一个进程,并具有特殊的角色。作为系统的父进程,init 进程负责启动和管理其他进程。由于其重要性和系统的稳定性需求,init 进程是不可被杀死的。

使用 jobspec 和 jobid 进行 Kill 进程

jobspec 和 job id:除了使用 PID 来标识进程外,kill 命令还接受 jobspec 作为参数。


jobspec 可以是作业的标识符,通常是由 shell 分配的一个唯一整数。使用 jobs 命令可以列出当前 shell 会话中正在运行或停止的作业及其对应的标识符(job id)。通过提供 job id 作为 kill 命令的参数,可以针对特定的作业执行操作。


要获取作业(job)的标识符(job id),可以通过使用以下命令来列出当前会话中的作业:


jobs
复制代码


执行该命令后,会显示当前会话中正在运行或停止的作业,并为每个作业分配一个唯一的 job id。


示例输出可能如下所示:


[1]  Running                 command1[2]- Stopped                 command2[3]+ Stopped                 command3
复制代码


在这个例子中,命令 1 具有 job id 1,命令 2 具有 job id 2,命令 3 具有 job id 3。


除了初始进程(pid=1)是无法被 kill 的之外,还有一种进程叫做僵尸进程(Zombie Process)。

僵尸进程

僵尸进程是 Linux 操作系统中的一个特殊状态,它表示进程已经结束了,但是仍然占用系统资源并且还没有被完全清理,就像僵尸一样。


由于僵尸进程不再执行任何代码,并且无法进行正常的交互,因此僵尸进程不会占用 CPU 资源,但会占用一些系统内存。僵尸进程的存在通常是由于父进程还没有对其进行处理(即收集其退出状态)。

僵尸进程产生的原因

正常情况下,父进程应该通过调用 wait()或 waitpid()等系统调用来获取子进程的退出状态,并释放子进程的相关资源。如果父进程没有正确处理子进程的退出状态,则子进程将变成僵尸进程。

僵尸进程存在的意义

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

僵尸进程的总结

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

Linux 进程状态

在 Linux 中,进程可以处于以下 5 种状态之一:



  • RUNNING(运行中):表示进程当前正在运行,或者在等待运行的状态。进程正在使用 CPU 执行其代码,或者正在等待分配 CPU 时间片来执行。

  • UNINTERRUPTIBLE(不可中断阻塞):表示进程正在等待某些资源(如磁盘 I/O)完成,而此时无法对其进行中断。进程处于这个状态时,不会响应大部分信号。

  • INTERRUPTIBLE(可中断阻塞):表示进程正在等待某些资源,但此时可以被中断。进程处于这个状态时可以接收并响应特定的信号。

  • STOPPED(已停止):表示进程已经被挂起或停止,并且不再执行任何操作。这是由于接收到了 SIGSTOP、SIGTSTP 或 SIGTTIN 等信号。

  • ZOMBIE(僵尸):表示进程已经结束了,但其父进程尚未通过 wait()系统调用来获取其退出状态,导致进程处于一种无法完全死亡的状态。僵尸进程占用系统资源,但不执行任何操作。

查看僵尸进程

使用 top 命令进行分析:


top - 14:34:38 up 305 days, 4:23,  2 users,  load average: 0.20, 0.29, 0.47Tasks:  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 stKiB Mem :  1882008 total,   525524 free,   311440 used,  1045044 buff/cacheKiB Swap:        0 total,        0 free,        0 used.  1382560 avail Mem 
复制代码


  • 时间信息:14:34:38,表示当前的时间。

  • 运行时间信息:up 305 days, 4:23,表示系统已经运行了 305 天 4 小时 23 分钟。

  • 用户和负载信息:2 users,表示当前有 2 个用户登录到系统上;load average: 0.20, 0.29, 0.47,表示过去 1 分钟、5 分钟和 15 分钟的平均负载情况。负载值表示系统上运行进程的平均数量,较低的负载值表示系统运行较轻松。

  • 任务信息:Tasks: 93 total,表示当前系统共有 93 个任务(进程),其中 1 个正在运行,92 个处于睡眠状态,0 个被停止,0 个为僵尸进程

  • CPU 占用信息:%Cpu(s): 2.0 us,表示用户空间进程所占用 CPU 的百分比;0.7 sy,表示内核进程所占用 CPU 的百分比;0.0 ni,表示用户进程以调整优先级的方式占用 CPU 的百分比;97.3 id,表示空闲 CPU 的百分比;0.0 wa,表示等待 I/O 完成的 CPU 百分比;0.0 hi,表示硬件中断占用 CPU 的百分比;0.0 si,表示软件中断占用 CPU 的百分比;0.0 st,表示被虚拟化环境偷取的 CPU 时间的百分比。

  • 内存使用信息:KiB Mem: 1882008 total,表示系统总内存容量为 1882008 KiB;525524 free,表示可用内存的容量为 525524 KiB;311440 used,表示已使用的内存的容量为 311440 KiB;1045044 buff/cache,表示用于缓存和缓冲的内存的容量为 1045044 KiB。

  • 交换空间使用信息:KiB Swap: 0 total,表示交换空间的总容量为 0 KiB;0 free,表示可用交换空间的容量为 0 KiB;0 used,表示已使用的交换空间的容量为 0 KiB;1382560 avail Mem,表示可用于内存分配的容量为 1382560 KiB。

发布于: 17 分钟前阅读数: 5
用户头像

洛神灬殇

关注

🏆 InfoQ写作平台-签约作者 🏆 2020-03-25 加入

👑 后端技术架构师,前优酷资深工程师 📕 个人著作《深入浅出Java虚拟机—JVM原理与实战》 💻 10年开发经验,参与过多个大型互联网项目,定期分享技术干货和项目经验

评论

发布
暂无评论
【Linux技术专题】「夯实基本功系列」带你一同学习和实践操作Linux服务器必学的Shell指令(深入Kill指令探索)_Linux_洛神灬殇_InfoQ写作社区