在 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
Capture SIGINT in Java
提问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 -2
will 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 -9
it did NOTrun the shutdown hook, didn't think it would. On a kill -15
it DOESrun the shutdown hook every time.
我试图在OSX 10.6.3以下测试程序和kill -9
它没有不运行关闭挂钩,没想到它会。在kill -15
它DOES运行关机钩每次。
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.misc
packages 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 java
command has had a -Xrs
flag 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 SIGQUIT
handlers, including one to explicitly call System.exit()
.
如果你使用它,你需要实现自己的SIGINT
,SIGTERM
,SIGHUP
,和SIGQUIT
处理程序,其中包括一个显式调用System.exit()
。
Note: this means the thread dump facility of SIGQUIT is disabled when the -Xrs
flag 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 java
counterparts).
请参阅https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BABHDABI(也可用于 Windows 和 Solarisjava
对应版本)。