如何杀死Java进程的子进程?
我正在使用 Process P1= Runtime.exec(...) 创建进程 P1。我的进程 P1 正在创建另一个进程,例如 P2、P3...
然后我想杀死进程 P1 以及 P1 创建的所有进程,即 P2、P3...
P1.destroy()
正在杀死仅 P1,而不是其子进程。
我也用谷歌搜索了一下,发现这是一个Java错误: https://bugs.java.com/bugdatabase/view_bug?bug_id=4770092
有人对如何做到这一点有任何想法吗?
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 i.e. P2, P3...
P1.destroy()
is killing P1 only, not its sub processes.
I also Googled it and found it's a Java bug:
https://bugs.java.com/bugdatabase/view_bug?bug_id=4770092
Does anyone have any ideas on how to do it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
是的,这是一个错误,但如果你阅读评估,就会发现根本问题是在 Windows 上实现“杀死所有小孩”几乎是不可能的。
答案是
P1
需要负责自己的整理工作。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.我遇到了类似的问题,我启动了一个 PowerShell 进程,该进程启动了一个 Ping 进程,当我停止我的 Java 应用程序时,PowerShell 进程将会终止(我会使用 Process.destroy() 来终止它),但是它创建的 Ping 进程不会。
经过一番尝试后,这个方法能够达到目的:
它杀死给定的进程及其所有子进程。
PS:您需要 Java 9 才能使用 Process.descendants() 方法。
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:
It kills the given Process and all of its sub-processes.
PS: You need Java 9 to use the
Process.descendants()
method.Java 不会公开任何有关子进程的信息,这是有充分理由的。如果您的子进程启动另一个进程,则由子进程来管理它们。
我建议要么
感谢 @Giacomo 在我之前建议 IPC。
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
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
要杀死子进程,java进程实例将不保证杀死所有相关的子进程。直到java 8,我们都没有正确的方法来获取进程的pid,因此您需要先执行以下操作来获取pid,然后对windows使用taskkill,对linux使用pkill。从java 9开始,你不需要担心pid。它只是 process.pid() 并使用该 pid 来终止进程。比如taskkill /PID pid /F /T。
To kill sub processes, java process instance will not guaranty to kill all related sub processes. Till java 8, we don't have proper method to get pid of process so you need to do following to get pid first and then use taskkill for windows and pkill for linux. From java 9, you don't need to worry about pid. it would be simply process.pid() and use that pid to kill the process. like taskkill /PID pid /F /T.
因为 Runtime.exec() 返回 的实例Process,您可以使用一些数组来存储它们的引用并稍后通过 Process.destroy()。
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().