2010-07-20 3 views
2

Je cours un processus Java sous Unix.Faire en sorte que le thread parent attende la fin ou l'expiration du thread enfant

Je dois exécuter un processus externe engendré par le processus principal à l'aide de ProcessBuilder. Le processus principal attend que le processus externe soit terminé, puis lance le processus externe suivant. Je l'ai travaillé jusqu'à ici.

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; 

}

Ce que je ne suis pas en mesure de comprendre, comment faire cela. Pour certaines entrées, le processus externe se bloque et, dans ce cas, je souhaite attendre un délai d'attente défini et si le processus externe n'est pas terminé, il suffit de le supprimer et de renvoyer le contrôle au processus principal (avec la valeur de sortie peut suivre les processus échoués), de sorte que le prochain processus externe peut être lancé.

J'ai essayé d'utiliser proc.wait (TIMEOUT), puis d'utiliser proc.exitValue(); pour obtenir la valeur de sortie, mais ne pouvait pas le faire fonctionner.

Merci!

+0

Process.wait (délai d'attente) est acutally la méthode wait() de la classe d'objet et ne doit pas être utilisé dans ce cas – naikus

Répondre

5

Vous pourriez faire Thread.join (long) ou Thread.join (long, int) et démarrer le processus dans un thread séparé.

Ajouter du code. (Works, mais pas complètement testé avec tous les cas d'angle)

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

essayé, et ça marche! Merci! – pkrish

Questions connexes