Java:等待所有子进程完成

4

环境:Windows 7

我正在使用ProcessBuilder启动一个外部进程。这个外部程序可以通过一个参数来调用,定义要使用多少个CPU核心。然后,它会启动尽可能多的进程来执行计算。

问题似乎是初始调用的进程立即终止了。因此,process.waitFor()实际上并没有等待计算完成。

如何让它等待子进程完成?或者如何等待特定名称的所有进程都被终止?

编辑由于评论:

ProcessBuilder pb = new ProcessBuilder("myExe", "-i", inputFile, "-o", outputFile, "-np", "4");
pb.directory(new File(tempPath));
Process myProcess = pb.start();
myProcess.waitFor();

进程是一个没有 GUI 的第三方可执行文件。

编辑 2:可能的解决方法(但还有另一个问题):

作为一种解决方法,我尝试了在 Google 上找到的一个解决方案:

while(wait) {       
    Process p = Runtime.getRuntime().exec(System.getenv("windir") +"\\system32\\"+"tasklist.exe /fi \"imagename eq myExe.exe\"");

    BufferedReader input =  new BufferedReader(new InputStreamReader(p.getInputStream(), "US-ASCII"));

    while ((line = input.readLine()) != null) {         
        if (line.startsWith("INFO: No tasks are running")) {
                wait = false; 
        }
    }
    if (wait) {
        Thread.sleep(2000);
    }
    input.close();
}

这应该返回所有具有给定名称的进程列表,但问题是当从Java中调用时,该列表总是为空,而在手动从cli中调用时,它可以正常工作。有什么想法为什么会出现这种情况?


你能展示一下你用于创建进程并等待它的代码吗? - Hulk
你的孩子处理 myExe 会产生更多的子进程吗? - Little Bobby Tables
@LittleBobbyTables 在我的情况下,它会生成与-np参数中指定的进程数相同的进程。我这里是4个(所有进程都运行与初始进程相同的exe文件)。 - beginner_
你尝试过捕获InterruptedException并检查waitFor()的返回值吗? - Hulk
你的父进程myExe是等待其子进程终止还是异步生成它们?Java代码等待的进程是否可能在其子进程之前终止? - Little Bobby Tables
显示剩余2条评论
1个回答

0
  • 类Java的不太优雅的解决方案

    目前,java.lang.Process相当简陋,但正在得到丰富。 例如,在Java 8中,您已经有了像isAlivedestroyForcibly这样的方法,因此您可以尝试以下不太优雅的解决方案:

    1. 通过反射获取主进程的ID
    2. 获取子进程 - 仅适用于Windows
    3. 等待找到的子进程

    步骤2和3可以实现为一个脚本,并作为java.lang.Process.waitFor执行。

  • 与可执行文件一起工作

    我想,可执行文件是某种MPI程序。如果您可以访问源代码,最好将其更改为正确工作并等待所有线程。


是的,你在MPI程序方面是正确的。然而修复这个问题不在范围之内。 - beginner_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接