写点什么

进程管理:kill 命令之 -9 与 -15

发布于: 2021 年 02 月 18 日
进程管理:kill命令之-9与-15

相关系列文章:

【Linux 系统】一个常驻进程问题的再次分析


一 进程状态转换



二 kill 命令回顾

kill :发送指定的信号到相应进程。不指定信号将发送 SIGTERM(15)终止指定进程。若仍无法终止该程序可用“-KILL” 参数,其发送的信号为 SIGKILL(9) ,将强制结束进程,使用 ps 命令或者 jobs 命令可以查看进程号。root 用户将影响用户的进程,非 root 用户只能影响自己的进程。

2.1 kill 命令参数

在命令行输入 kill,可以看到参数提示如下:

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

参数说明:

-l <信号编号>,若不加信号的编号参数,则使用“-l”参数会列出全部的信号名称。常用的 kill -15,kill -9 这里的 9 和 15 就是信号;

-a 当处理当前进程时,不限制命令名和进程号的对应关系;

-p 指定 kill 命令只打印相关进程的进程号,而不发送任何信号;

-s 指定发送信号;

-u 指定用户;

2.2 信号

使用 kill -l 可以列举所有支持的信号:

[admin@test-3 ~]$ kill -l 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
复制代码

也可以通过 kill -l SIGHUP 查指定信号对应的数值:

[admin@test-3 ~]$ kill -l SIGHUP1
复制代码

几个常用的信号如下:

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

其中,信号如果没有指定的话,默认会发出终止信号(15)。比较常用的就是强制终止信号:9终止信号:15,另外,中断信号:2其实就是 Ctrl + C 结束前台进程。

2.3 kill -15 与 kill -9

当我们使用 kill pid 时,实际相当于 kill -15 pid。也就是说默认信号为 15。使用kill -15时,系统会发送一个 SIGTERM 的信号给对应的程序。当程序接收到该信号后,具体要如何处理自己可以决定。

这时候,应用程序可以选择:

  • 1、立即停止程序

  • 2、释放响应资源后停止程序

  • 3、忽略该信号,继续执行程序

因为kill -15信号只是通知对应的进程要进行"安全、干净的退出",程序接到信号之后,退出前一般会进行一些"准备工作",如资源释放、临时文件清理等等,如果准备工作做完了,再进行程序的终止。

但是,如果在"准备工作"进行过程中,遇到阻塞或者其他问题导致无法成功,那么应用程序可以选择忽略该终止信号。

这也就是为什么我们有的时候使用 kill 命令是没办法"杀死"应用的原因,因为默认的 kill 信号是 SIGTERM(15),而 SIGTERM(15)的信号是可以被阻塞和忽略的。

kill -15相比,kill -9就相对强硬得多,系统会发出 SIGKILL 信号,他要求接收到该信号的程序应该立即结束运行,不能被阻塞或者忽略。

所以,kill -9 在执行时,应用程序是没有时间进行"准备工作"的,所以这通常会带来一些副作用,数据丢失或者终端无法恢复到正常状态等。

三 Java 应用对 SIGTERM 信号的处理

Java 应用在 Linux 中是以一个独立进程的形式运行的,Java 程序的终止运行基于 JVM 的关闭实现,JVM 关闭方式分为 3 种:

正常关闭:当最后一个非守护线程结束或者调用了 System.exit 或者通过其他特定平台的方法关闭(接收到 SIGINT(2)、SIGTERM(15)信号等)

强制关闭:通过调用 Runtime.halt 方法或者是在操作系统中强制 kill(接收到 SIGKILL(9)信号)

异常关闭:运行中遇到 RuntimeException 异常等。


JVM 进程在接收到kill -15信号通知的时候,会做一些清理动作的,例如删除临时文件。同时,也提供了 hook 机制,来让开发者自定义清理动作,对应的方法为:Java.Runtime.addShutdownHook(Thread hook)。我们可以自定义一个 shuthook 并测试效果:

package shutdown;import java.util.concurrent.TimeUnit;
public class MyShutdownHook { public static void main(String[] args) throws InterruptedException{ boolean flag = true; Runtime.getRuntime().addShutdownHook(new Thread(() -> { System.out.println("my hook execute end"); }));
while (flag) { System.out.println("my app is running"); TimeUnit.SECONDS.sleep(3); } System.out.println("main thread execute end"); }}
复制代码

在 IDE 内执行后,进程会一直存在,我们在其中加了一个死循环保证进程常驻,且每 3 秒钟打印一次 app 正在运行中。通过 jps 命令查看进程 id,并执行 kill 命令,查看执行效果:

192:dubbo-proxy-tools xxx$ jps24272 6178 Launcher6179 MyShutdownHook6182 Jps99256 RemoteMavenServer585 UserClient24446 war192:dubbo-proxy-tools xxx$ kill 6179
复制代码

其中 6179 MyShutdownHook 是我们的这个程序运行进程。执行 kill 后可以看到程序运行控制台的输出如下:

my app is runningmy app is runningmy app is runningmy hook execute end
Process finished with exit code 143 (interrupted by signal 15: SIGTERM)
复制代码

可见 hook 被执行,并且给了接收到 signal 15 信号的提示后,线程中断,所以没有执行结尾的打印主线程退出记录(第 13 行的 System.out.println("main thread execute end");)。

再次运行程序,我们来看看 kill -9 执行的效果:

my app is runningmy app is running
Process finished with exit code 137 (interrupted by signal 9: SIGKILL)
复制代码

可见 kill -9 强杀进程后,没有执行 shutdownHook,而是直接退出。给出的提示为:interrupted by signal 9: SIGKILL

发布于: 2021 年 02 月 18 日阅读数: 23
用户头像

磨炼中成长,痛苦中前行 2017.10.22 加入

微信公众号【程序员架构进阶】。多年项目实践,架构设计经验。曲折中向前,分享经验和教训

评论

发布
暂无评论
进程管理:kill命令之-9与-15