Java中如何优雅地处理SIGKILL信号 [英] How to gracefully handle the SIGKILL signal in Java

查看:72
本文介绍了Java中如何优雅地处理SIGKILL信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当程序收到终止信号时,您如何处理清理?

How do you handle clean up when the program receives a kill signal?

例如,我连接到一个应用程序,它希望任何第三方应用程序(我的应用程序)在注销时发送 finish 命令.当我的应用程序被 kill -9 销毁时,发送 finish 命令的最佳方式是什么?

For instance, there is an application I connect to that wants any third party app (my app) to send a finish command when logging out. What is the best say to send that finish command when my app has been destroyed with a kill -9?

edit 1: kill -9 不能被捕获.谢谢大家纠正我.

edit 1: kill -9 cannot be captured. Thank you guys for correcting me.

编辑 2:我想这种情况是当一个调用 just kill 时,这与 ctrl-c 相同

edit 2: I guess this case would be when the one calls just kill which is the same as ctrl-c

推荐答案

任何语言的任何程序不可能处理 SIGKILL.因此,即使程序有错误或恶意,也始终可以终止程序.但是 SIGKILL 不是终止程序的唯一方法.另一种是使用SIGTERM.程序可以处理那个信号.程序应该通过执行受控但快速的关闭来处理信号.当计算机关闭时,关闭过程的最后阶段向每个剩余的进程发送一个 SIGTERM,给这些进程几秒钟的宽限期,然后向它们发送一个 SIGKILL.

It is impossible for any program, in any language, to handle a SIGKILL. This is so it is always possible to terminate a program, even if the program is buggy or malicious. But SIGKILL is not the only means for terminating a program. The other is to use a SIGTERM. Programs can handle that signal. The program should handle the signal by doing a controlled, but rapid, shutdown. When a computer shuts down, the final stage of the shutdown process sends every remaining process a SIGTERM, gives those processes a few seconds grace, then sends them a SIGKILL.

处理任何其他而不是kill -9的方法是注册一个关闭 钩子.如果您可以使用 (SIGTERM) kill -15 关闭挂钩将起作用.(SIGINT) kill -2 DOES 导致程序正常退出并运行关闭钩子.

The way to handle this for anything other than kill -9 would be to register a shutdown hook. If you can use (SIGTERM) kill -15 the shutdown hook will work. (SIGINT) kill -2 DOES cause the program to gracefully exit and run the shutdown hooks.

注册一个新的虚拟机关闭钩子.

Registers a new virtual-machine shutdown hook.

Java 虚拟机关闭以响应两种事件:

The Java virtual machine shuts down in response to two kinds of events:

  • 程序正常退出,当最后一个非守护线程退出或退出(相当于 System.exit)方法被调用时,或
  • 虚拟机在响应用户中断(例如键入 ^C)或系统范围事件(例如用户注销或系统关闭)时终止.

我在 OSX 10.6.3 和 kill -9 上尝试了以下测试程序,它确实按预期运行关闭挂钩.在 kill -15 上,它确实每次都运行关闭钩子.

I tried the following test program on OSX 10.6.3 and on kill -9 it did NOT run the shutdown hook, as expected. On a kill -15 it DOES run the shutdown hook every time.

public class TestShutdownHook
{
    public static void main(String[] args) throws InterruptedException
    {
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                System.out.println("Shutdown hook ran!");
            }
        });

        while (true)
        {
            Thread.sleep(1000);
        }
    }
}

没有任何方法可以真正优雅地处理任何程序中的 kill -9.

There isn't any way to really gracefully handle a kill -9 in any program.

在极少数情况下,虚拟机器可能会中止,即停止运行而不干净地关闭.这发生在虚拟机在外部终止,例如在 Unix 上使用 SIGKILL 信号或微软的 TerminateProcess 调用窗户.

In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly. This occurs when the virtual machine is terminated externally, for example with the SIGKILL signal on Unix or the TerminateProcess call on Microsoft Windows.

处理 kill -9 的唯一真正选择是让另一个观察程序监视您的主程序或使用包装脚本.您可以使用一个 shell 脚本来完成此操作,该脚本轮询 ps 命令以在列表中查找您的程序,并在它消失时采取相应措施.

The only real option to handle a kill -9 is to have another watcher program watch for your main program to go away or use a wrapper script. You could do with this with a shell script that polled the ps command looking for your program in the list and act accordingly when it disappeared.

#!/usr/bin/env bash

java TestShutdownHook
wait
# notify your other app that you quit
echo "TestShutdownHook quit"

这篇关于Java中如何优雅地处理SIGKILL信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆