如何杀死Java进程的子进程?

如何杀死Java进程的子进程?,java,process,runtime,runtime.exec,Java,Process,Runtime,Runtime.exec,我正在使用processp1=Runtime.exec(…)创建一个进程P1。我的流程P1正在创建另一个流程,比如P2,P3 然后我想终止进程P1和由P1创建的所有进程,即P2,P3 P1.destroy()只杀死P1,而不是它的子进程 我还用谷歌搜索了一下,发现这是一个Java错误: 有人对如何做到这一点有什么想法吗?您是在编写其他流程的代码,还是无法更改 如果你可以,我会考虑修改它们,让他们接受某种消息(即使通过标准流),这样他们就很好地终止请求,如果他们自己有,就终止孩子。 我不认为“销

我正在使用
processp1=Runtime.exec(…)
创建一个进程P1。我的流程P1正在创建另一个流程,比如P2,P3

然后我想终止进程P1和由P1创建的所有进程,即P2,P3

P1.destroy()
只杀死P1,而不是它的子进程

我还用谷歌搜索了一下,发现这是一个Java错误:


有人对如何做到这一点有什么想法吗?

您是在编写其他流程的代码,还是无法更改

如果你可以,我会考虑修改它们,让他们接受某种消息(即使通过标准流),这样他们就很好地终止请求,如果他们自己有,就终止孩子。


我不认为“销毁进程”是一件干净的事情。

如果它是bug,正如您所说,那么您必须跟踪子进程的进程树,并在想要杀死父进程时从树中杀死所有子进程
为此,您需要使用数据结构树,如果由于Runtime.exec()返回的实例,您只有两个进程而不是use list,那么您可以使用一些数组来存储它们的引用,并在以后通过删除它们。

Java没有充分的理由公开关于进程子进程的任何信息。如果您的子进程启动另一个进程,则由子进程来管理它们

我建议两者都可以

  • 重构您的设计,以便父进程创建/控制所有子进程,或
  • 使用操作系统命令销毁进程,或
  • 使用另一种控制机制,比如某种形式的进程间通信(有很多Java库是为此而设计的)

感谢@Giacomo在我面前建议IPC。

是的,这是一个Bug,但是如果你阅读评估,潜在的问题是在Windows上几乎不可能实现“杀死所有的小孩”


答案是,
P1
需要负责自己的清理工作。

我遇到了一个类似的问题,我启动了一个启动Ping进程的PowerShell进程,当我停止我的Java应用程序时,PowerShell进程将死亡(我将使用
Process.destroy()
杀死它)但它创建的Ping过程不会

在使用它之后,这种方法能够实现以下目的:

private void stopProcess(Process process) {
    process.descendants().forEach(new Consumer<ProcessHandle>() {
        @Override
        public void accept(ProcessHandle t) {
            t.destroy();
        }
    });
    process.destroy();
}
private void stopproces(进程){
process.subjects().forEach(新使用者(){
@凌驾
公共无效接受(ProcessHandle t){
t、 破坏();
}
});
process.destroy();
}
它杀死给定进程及其所有子进程


PS:您需要Java9来使用
Process.substands()
方法。

您能获得子流程的流程id吗?也许你可以通过Runtime.exec()再次杀死它们。截至2017年5月12日,该漏洞已被关闭为“无法修复”。我建议依赖本机操作系统调用来关闭子进程。这个问题涉及到由Java执行的进程的子进程