2010-07-20 79 views
2

我在UNIX上運行Java進程。讓父線程等到子線程完成或超時

我需要運行使用ProcessBuilder由主進程產生的外部進程。主進程等待,直到外部進程完成,然後產生下一個外部進程。我已經在這裏工作了。

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; 

}

我什麼不能出來就是,如何做到這一點的身影。對於某些輸入來說,外部進程會掛起,在這種情況下,我想等待一段設定的超時時間,如果外部進程沒有完成,只需將其終止並將控制權返回給主進程(與退出值一起),以便我可以跟蹤失敗的進程),以便下一個外部進程可以啓動。我嘗試使用proc.wait(超時),然後使用proc.exitValue();我試過使用proc.wait(超時),然後使用proc.exitValue()。獲得退出價值,但不能得到它的工作。

謝謝!

+0

Process.wait(超時)是實際上可以從對象類的wait()方法,不應該在這種情況下 – naikus 2010-07-20 18:14:14

回答

5

你可以做Thread.join(long)或Thread.join(long,int)並在單獨的線程中啓動進程。

添加一些代碼。 (運作,但並不完全符合所有角落的情況下測試)

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(); 
      } 
     } 
    } 
    } 
+0

試過這種使用,和它的作品!謝謝! – pkrish 2010-07-20 21:14:55