在 Java 中捕获 SIGINT

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2541475/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:04:32  来源:igfitidea点击:

Capture SIGINT in Java

javasignals

提问by Begui

What is the best way to capture a kill signal in java without using JNI. I did discover the sun.misc.Signal and the sun.misc.SignalHandler and the warning of the possibility of being removed in the future releases.

在不使用 JNI 的情况下在 Java 中捕获终止信号的最佳方法是什么。我确实发现了 sun.misc.Signal 和 sun.misc.SignalHandler 以及在未来版本中可能被删除的警告。

Would using JNI to call a c lib be the only option i have?

使用 JNI 调用 ac lib 是我唯一的选择吗?

采纳答案by Asgeir S. Nilsen

The way to handle this would be to register a shutdownhook. If you use (SIGINT) kill -2will cause the program to gracefully exit and run the shutdown hooks.

处理这个问题的方法是注册一个关闭钩子。如果使用 ( SIGINT)kill -2将导致程序正常退出并运行关闭挂钩。

Registers a new virtual-machine shutdown hook.

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

  • The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or

  • The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.

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

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

  • 程序正常退出,当最后一个非守护线程退出或调用退出(相当于 System.exit)方法时,或

  • 虚拟机响应用户中断(例如键入 ^C)或系统范围的事件(例如用户注销或系统关闭)而终止。

I tried the following test program on OSX 10.6.3 and on kill -9it did NOTrun the shutdown hook, didn't think it would. On a kill -15it DOESrun the shutdown hook every time.

我试图在OSX 10.6.3以下测试程序和kill -9它没有运行关闭挂钩,没想到它会。在kill -15DOES运行关机钩每次。

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

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

This is the documented way to write your own signal handlersthat aren't shutdown hooks in Java. Be warnedthat the com.sun.miscpackages and are un-supported and may be changed or go away at any time and probably only exist in the Sun JVM.

这是编写自己的信号处理程序的文档化方法,这些处理程序不是 Java 中的关闭挂钩。被警告com.sun.misc包并为联合国支持,并可以改变或消失在任何时候,大概只有在Sun JVM存在。

回答by Asgeir S. Nilsen

Take a look at Integrating Signal and Exception Handlingdescribing the HotSpot JVM's ability do do signal chaining. It does involve some C-level trickery though.

看一看集成信号和异常处理描述 HotSpot JVM 的能力做信号链。不过,它确实涉及一些 C 级技巧。

Wouldn't java.lang.Runtime.addShutdownHook(Thread)be enough for your purpose? These hooks are run by the JVM upon termination, including reception of SIGINT, as long as the JVM is able to perform them.

java.lang.Runtime.addShutdownHook(Thread)对你的目的来说还不够吗?这些钩子在终止时由 JVM 运行,包括接收SIGINT,只要 JVM 能够执行它们。

回答by delitescere

Since at least Java 6, the HotSpot javacommand has had a -Xrsflag to disable the JVM signal handlers.

至少从 Java 6 开始,HotSpotjava命令有一个-Xrs标志来禁用 JVM 信号处理程序。

If you use it, you need to implement your own SIGINT, SIGTERM, SIGHUP, and SIGQUIThandlers, including one to explicitly call System.exit().

如果你使用它,你需要实现自己的SIGINTSIGTERMSIGHUP,和SIGQUIT处理程序,其中包括一个显式调用System.exit()

Note: this means the thread dump facility of SIGQUIT is disabled when the -Xrsflag is present.

注意:这意味着当-Xrs标志存在时,SIGQUIT 的线程转储工具被禁用。

See https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BABHDABI(also available on the Windows and Solaris javacounterparts).

请参阅https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BABHDABI(也可用于 Windows 和 Solarisjava对应版本)。