简体   繁体   中英

How to kill subprocesses of a Java process?

I am creating a process P1 by using Process P1= Runtime.exec(...) . My process P1 is creating another process say P2, P3....

Then I want to kill process P1 and all the processes created by P1 ie P2, P3...

P1.destroy() is killing P1 only, not its sub processes.

I also Googled it and found it's a Java bug: 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.

The answer is that P1 needs to be responsible for doing its own tidy-up.

Java does not expose any information on process grandchildren with good reason. 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).

Props to @Giacomo for suggesting the IPC before me.

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

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.

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.

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() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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