如何在Linux和Windows中优雅地停止Java进程?
何时Runtime.getRuntime().addShutdownHook被召唤,什么时候不召唤?
终结者怎么样,他们在这里有帮助吗?
我可以从shell向Java进程发送某种信号吗?
我正在寻找最好的便携式解决方案.
Linux支持使用-Command 将任意Posix-Signal发送到进程SIGINT或SIGTERM发送到进程kill.虽然SIGINT并且SIGTERM只是无聊的方式以友好或不那么友好的方式结束流程,但SIGQUIT意味着触发核心转储.这可以用来触发正在运行的Java VM打印出一个线程转储,包括所有正在运行的线程的堆栈跟踪 - 整洁!打印完调试信息后,Java VM将继续执行以前的操作; 事实上,线程转储只发生在另一个具有最高优先级的衍生线程中.(您可以通过使用自己尝试kill -3 <VM-PID>.)
请注意,您也可以使用(不支持的!)Signal和-package中的SignalHandler类注册自己的信号处理程序sun.misc,这样您就可以获得各种乐趣.
但是,我还没有找到一种向Windows进程发送信号的方法.信号由某些用户输入创建:例如,在两个平台上Ctrl-C触发a SIGINT.但是,在Windows上手动将信号发送到正在运行但非交互式的进程似乎没有任何实用性.显而易见的解决方案是使用Cygwin kill可执行文件,但是虽然它可以使用适当的Windows API结束Windows进程,但我无法使用它发送SIGBREAK(Windows等效SIGQUIT); 事实上,我认为它能够发送到Windows进程的唯一信号是SIGTERM.
因此,长话短说并重复标题:如何向Windows中的进程发送任意信号?
在Linux中,当我在java.lang.Process对象上运行destroy函数(这是真正的类型java.lang.UNIXProcess)时,它会发送一个SIGTERM信号进行处理,有没有办法用SIGKILL来杀死它?
如何从JVM中发送POSIX信号?(在Java或Clojure中)
在我尝试使用谷歌搜索之前,我从未想过这会成为一个问题 - 有很多关于处理信号的信息,但没有关于发送它们的信息.
如果没有使用JNI或调用shell来执行"kill",还有其他方法可以向PID发送信号吗?
我听说在 Java 9 中他们做了很多工作来更新 Process API。现在是否有一种更简洁的方式向ProcessJava 产生的发送信号?这些信号用作在过程中触发操作的简单方法。
之前我不得不使用反射来获取一个pid然后使用Runtime#exec来发送kill命令。我假设您仍然需要使用,Runtime#exec因为信号可能取决于操作系统,但我很好奇是否有人知道比这更好的方法!
Process p = Runtime.getRuntime().exec(...);
...
Runtime.getRuntime().exec("kill -SIGUSR1 " + p.getPid());
Run Code Online (Sandbox Code Playgroud)