简体   繁体   中英

Make parent thread wait till child thread completes or timeout

I am running a Java process on unix.

I need to run an external process which is spawned by the main process using ProcessBuilder. The main process waits until the external process is done, and then spawnes the next external process. I have got it working till here.

public static void main(String[] args) { for(...) { int exitVal = runExternalProcess(args); if(exitVal !=0) { failedProcess.add(args); } } }

private int runExternalProcess(String[] args) { ProcessBuilder pb = new ProcessBuilder(args[0], args[1], args[2]); pb.redirectErrorStream(true); Process proc = pb.start(); BufferedReader br = new BufferedReader(new InputStreamReader( proc.getInputStream())); String line = null; while ( (line = br.readLine()) != null) LOG.log(Level.SEVERE, line);

//Main thread waits for external process to complete.
//What I need to do is. 
// If proc.executionTime() > TIMEOUT
//     kill proc;         
int exitVal = proc.waitFor();

proc.getInputStream().close();
proc.getOutputStream().close();
proc.getErrorStream().close();

return exitVal;

}

What I am not able to figure out is, how to do this. For some inputs the external process hangs and in such cases, I want to wait for a set timeout period and if the external process is not complete by then, just kill it and return control to the main process (along with exit value so that I can track the failed processes), so that the next external process can be launched.

I tried using proc.wait(TIMEOUT) and then using proc.exitValue(); to get the exit value, but could not get it working.

Thanks!

YOu could do Thread.join(long) or Thread.join(long, int) and start process in separate thread.

Adding some code. (Works but Not fully tested with all corner cases)

  public class Test {

     public static void main(String[] args) throws Throwable  {
        for(int i = 0; i < 3; i++) {
           ProcessRunner pr = new ProcessRunner(args);
           pr.start();
           // wait for 100 ms
           pr.join(100);
           // process still going on? kill it!
           if(!pr.isDone())  {
              System.err.println("Destroying process " + pr);
              pr.abort();
           }
        }
     }

     static class ProcessRunner extends Thread  {
        ProcessBuilder b;
        Process p;
        boolean done = false;

        ProcessRunner(String[] args)  {
           super("ProcessRunner " + args); // got lazy here :D
           b = new ProcessBuilder(args);
        }

        public void run()   {
           try   {
              p = b.start();

              // Do your buffered reader and readline stuff here

              // wait for the process to complete
              p.waitFor();
           }catch(Exception e) {
              System.err.println(e.getMessage());
           }finally {
              // some cleanup code
              done = true;
           }
        }

        int exitValue() throws IllegalStateException  {
           if(p != null)  {
              return p.exitValue();
           }         
           throw new IllegalStateException("Process not started yet");
        }

        boolean isDone()  {
           return done;
        }

        void abort()   {
           if(! isDone()) {
              // do some cleanup first
              p.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