4

Environment: Windows 7

I'm launching an external process with ProcessBuilder. This external program can be called with an argument defining how many CPU cores to use. It then launches as many processes to perform the calculation.

The issue seems to be that the initial called process then immediately terminates. So process.waitFor() does not actually wait for the calculation to complete.

How can I make it wait for the child-process it spwaned? Or how can i wait til all process of a specific name have been terminated?

EDIT due to comments:

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

Process is a 3-rd party exe file (no GUI).

EDIT 2 Possible workaround (which has another issue):

As a workaround I tried a solution found with 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();
}

This should return a list of all processes with the given name. Problem is the list is always empty when called from Java but works correctly when called from the cli manually. Any ideas why?

beginner_
  • 7,230
  • 18
  • 70
  • 127
  • Can you show us the code you use for creating the process and waiting for it? – Hulk Nov 09 '15 at 06:41
  • Also possibly relevant: what kind of process do you create? As the JavaDocs for [Process](https://docs.oracle.com/javase/8/docs/api/java/lang/Process.html) states: `The methods that create processes may not work well for special processes on certain native platforms, such as native windowing processes, daemon processes, Win16/DOS processes on Microsoft Windows, or shell scripts.` – Hulk Nov 09 '15 at 06:46
  • Does your child process `myExe` spawns more child-processes? – Little Bobby Tables Nov 09 '15 at 07:08
  • @LittleBobbyTables it spawns as many processes as specified in the -np argument. In my case 4 (all run the same exe file as the initial process). – beginner_ Nov 09 '15 at 08:05
  • Have you tried catching the InterruptedException and checking the return value of waitFor()? – Hulk Nov 09 '15 at 08:19
  • Does your parent process `myExe` waits for the termination of its child-processes or spawns them asynchronously? Is it possible that the process that the Java code waits upon terminates before its children? – Little Bobby Tables Nov 09 '15 at 09:05
  • @LittleBobbyTables Yes, parent seems to spwan children and then terminates. That's why waitFor() will be useless because it is applied to this parent process. – beginner_ Nov 09 '15 at 11:39

1 Answers1

0
  • Java-like dirty solution

    Currently java.lang.Process is rather poor and is getting enriched. For example, here you can find the feature requests. In java 8, you already have methods like isAlive and destroyForcibly So you can try something like the following dirty solution:

    1. Get the id of the main process by reflection.
    2. Get the child processes - specific for Windows
    3. Wait for the found child processes

    Steps 2 and 3 can be implemented as one script and executed as java.lang.Process.waitFor

  • Work with the executable

    I suppose, that the executable is some kind of MPI program. If you have access to the sources, i'd better change it to work correctly and waiting for all threads.

Community
  • 1
  • 1
Dmitrii Bocharov
  • 872
  • 6
  • 21