简体   繁体   English

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

[英]How to kill subprocesses of a Java process?

I am creating a process P1 by using Process P1= Runtime.exec(...) .我正在使用Process P1= Runtime.exec(...)创建一个进程 P1。 My process P1 is creating another process say P2, P3....我的进程 P1 正在创建另一个进程,比如 P2、P3 ....

Then I want to kill process P1 and all the processes created by P1 ie P2, P3...然后我想杀死进程 P1 和 P1 创建的所有进程,即 P2、P3 ......

P1.destroy() is killing P1 only, not its sub processes. P1.destroy()只杀死 P1,而不是它的子进程。

I also Googled it and found it's a Java bug: http://bugs.sun.com/view_bug.do?bug_id=4770092我也用谷歌搜索了它,发现它是一个 Java 错误: http://bugs.sun.com/view_bug.do?bug_id=4770092

Does anyone have any ideas on how to do it?有人对如何做有任何想法吗?

Yes, it is a Bug, but if you read the evaluation the underlying problem is that it is next to impossible to implement "kill all the little children" on Windows.是的,这是一个错误,但如果您阅读评估,则根本问题是在 Windows 上实现“杀死所有小孩”几乎是不可能的。

The answer is that P1 needs to be responsible for doing its own tidy-up.答案是P1需要负责自己的整理工作。

Java does not expose any information on process grandchildren with good reason. Java 没有充分理由公开有关进程孙子的任何信息。 If your child process starts another process then it is up to the child process to manage them.如果您的子进程启动另一个进程,则由子进程来管理它们。

I would suggest either我建议要么

  • Refactoring your design so that your parent creates/controls all child processes, or重构您的设计,以便您的父级创建/控制所有子进程,或
  • Using operating system commands to destroy processes, or使用操作系统命令破坏进程,或
  • Using another mechanism of control like some form of Inter-Process Communication (there are plenty of Java libraries out there designed for this).使用另一种控制机制,例如某种形式的进程间通信(有很多为此设计的 Java 库)。

Props to @Giacomo for suggesting the IPC before me.支持@Giacomo 在我之前建议 IPC。

Is you writing other processes' code or they are something you cannot change?您是在编写其他进程的代码还是您无法更改它们?

If you can, I would consider modifying them so that they accept some kind of messages (even through standard streams) so they nicely terminate upon request, terminating children if they have, on their own.如果可以的话,我会考虑修改它们,以便它们接受某种消息(甚至通过标准流),这样它们就可以根据请求很好地终止,如果有的话,可以自行终止孩子。

I don't find that "destroying process" something clean.我不认为“破坏过程”是干净的。

if it is bug, as you say then you must keep track pf process tree of child process and kill all child process from tree when you want to kill parent process you need to use data structure tree for that, if you have only couple of process than use list如果它是错误,如您所说,那么您必须跟踪子进程的 pf 进程树,并在要杀死父进程时从树中杀死所有子进程,如果您只有几个进程,则需要使用数据结构树比使用列表

I had a similar issue where I started a PowerShell Process which started a Ping Process, and when I stopped my Java Application the PowerShell Process would die (I would use Process.destroy() to kill it) but the Ping Process it created wouldn't.我有一个类似的问题,我启动了一个启动 Ping 进程的 PowerShell 进程,当我停止我的 Java 应用程序时,PowerShell 进程会死掉Process.destroy()我会使用 Processing.destroy 来杀死它)吨。

After messing around with it this method was able to do the trick:在弄乱它之后,这个方法能够做到这一点:

private void stopProcess(Process process) {
    process.descendants().forEach(new Consumer<ProcessHandle>() {
        @Override
        public void accept(ProcessHandle t) {
            t.destroy();
        }
    });
    process.destroy();
}

It kills the given Process and all of its sub-processes.它杀死给定的进程及其所有子进程。

PS: You need Java 9 to use the Process.descendants() method. PS:您需要 Java 9 才能使用Process.descendants()方法。

Because the Runtime.exec() return a instance of Process , you can use some array to store their reference and kill them later by Process.destroy() .因为 Runtime.exec() 返回Process的一个实例,所以您可以使用一些数组来存储它们的引用,并在稍后通过Process.destroy()杀死它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM