【问题标题】:How to kill subprocesses of a Java process?如何杀死Java进程的子进程?
【发布时间】:2011-05-04 07:11:49
【问题描述】:

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

然后我想杀死进程 P1 和 P1 创建的所有进程,即 P2、P3...

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

我也用 Google 搜索了一下,发现这是一个 Java 错误: http://bugs.sun.com/view_bug.do?bug_id=4770092

有人对如何做有任何想法吗?

【问题讨论】:

  • 能否获取子进程的进程id?也许你可以再次通过 Runtime.exec() 杀死它们。
  • 截至 2017 年 5 月 12 日,该错误已被关闭为“不会修复”。我建议依靠本机操作系统调用来关闭子进程。

标签: java process runtime runtime.exec


【解决方案1】:

是的,这是一个错误,但如果您阅读评估,则根本问题是在 Windows 上实现“杀死所有小孩”几乎是不可能的。

答案是P1需要自己负责整理。

【讨论】:

    【解决方案2】:

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

    我也建议

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

    感谢@Giacomo 在我面前推荐 IPC。

    【讨论】:

      【解决方案3】:

      您是在编写其他进程的代码还是您无法更改它们?

      如果可以的话,我会考虑修改它们,以便它们接受某种类型的消息(甚至通过标准流),这样它们就可以根据请求很好地终止,如果有子节点,则自行终止。

      我不认为“破坏过程”是干净的。

      【讨论】:

        【解决方案4】:

        如果是错误,如您所说,那么您必须跟踪子进程的 pf 进程树,并在您想杀死父进程时从树中杀死所有子进程 你需要使用数据结构树,如果你只有几个进程而不是使用列表

        【讨论】:

          【解决方案5】:

          我有一个类似的问题,我启动了一个启动 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();
          }
          

          它会杀死给定的进程及其所有子进程。

          PS:您需要 Java 9 才能使用 Process.descendants() 方法。

          【讨论】:

            【解决方案6】:

            因为 Runtime.exec() 返回一个Process 的实例,所以您可以使用一些数组来存储它们的引用,并在以后通过Process.destroy() 杀死它们。

            【讨论】:

            • 问题是关于有 Java 执行的进程的子进程
            最近更新 更多