Newsgroup: it.comp.java
Titolo: Is a thread running?

How can I know if a subprocess that I run with
Runtime.getRuntime().exec(....) is running without blocking?
Have I to use exitValue() and catch the IllegalThreadStateException?
W.

if it is a Thread why don't use active o running method tha say to you when
tyhe thread is still runinng or not?

 the thread is still runinng or not?

 
visto che il ng e` it.* ti rispondo in italiano...
Penso che cmq ti convenga creare un thread secondario che
aspetti l'uscita del processo figlio. Poi, come tu dici, puoi
utilizzare exitValue() (la quale solleva un'eccezione se il
processo figlio ancora non e` terminato), oppure, se segui il
consiglio di utilizzare un thread apposito, ti conviene usare
waitFor(), che blocca il thread finche` non riceve risposta
dal processo.
personalmente ritengo piu` "pulita" la soluzione con waitFor().
exitValue() inoltre non e` bloccante: puoi dover ripetere il
test piu` volte.
-- 
Ciao,  |  I play Russian roulette everyday, a man's sport,
Matteo |  With a bullet called life, yeah called life, (SUGAR)

 dal processo.
[....]
Forse adesso che ho spiegato in maggior dettaglio il mio problema dovrebbe
essere piu' chiaro perche' non posso usare la waitFor(). Oppure se si puo'
usare mi dovresti rispiegare perche' non escludo di non aver capito.
W.

esiste un metodo dell'oggetto Thread che dice se esso è tuttora running
oppure no.
Ovviamente funziona solo se l'oggeto del thread tu lo conosci, almeno io
l'ho usato avendone a disposizione un'istanza...
Sull'API di Thread dovresi trovarlo.

 
no: il thread principale fa partire il processo figlio, un'altro si
occupa di controllarne l'uscita, permettendoti cosi` al thread principale
di "fare altro" nell'attesa. Se poi invece non ti interessa fare altro ma
devi solo attendere, l'utilizzo di un thread secondario e` superfluo.
Dunque *se* ho capito cio` che ti serve, io fare +/- cosi`:
poniamo di avere una classe "Timer", che ci permette di ricevere
notifiche ad intervalli di tempo prestabiliti.
- Il tuo programma lancia il processo figlio.
- Il tuo programma fa partire un timer che scade dopo x minuti
- Il tuo programma fa una waitFor() e si sospende, in attesa
  che il processo figlio termini.
A questo punto
1a possibilita`: il processo figlio termina _prima_ degli x minuti:
- il tuo programma ferma il timer, che non e` piu` necessario, e
  stampa il codice di ritorno del processo figlio
2a possibilita`: il processo figlio non riesce a terminare entro gli
x minuti stabiliti come limite massimo di tempo:
- il tuo programma riceve notifica dal timer, "si sveglia", e termina
  il processo figlio segnalando a video un messaggio di tempo scaduto
OSS: il programma, nonostante sia sospeso su una waitFor(), puo`
     facilmente ricevere notifiche dal timer poiche` questo verra`
     implementato come thread separato, che comunica lo scadere del
     timeout tramite funzioni "callback".
In definitiva il codice sarebbe questo:
/* ------------------- file Timed.java ------------------- */
/**
 * Interfaccia da implementare per l'utilizzo di Timer
 * da parte di un'altra classe.
 * Il Timer utilizzato chiamera' il metodo tick ad ogni timeout.
 */
public interface Timed
{
    void tick( Timer timer );
} // :~
/* ------------------- file Timer.java ------------------- */
/**
 * Timer: un semplice timer implementato tramite Thread in grado
 * di segnalare ad un oggetto Timed lo scadere di un timeout.
 */
public class Timer extends Thread
{
// Fields
    /** oggetto cui segnalare lo scadere del timeout */
    private Timed target;
    /** timeout (in millisecondi) */
    private int interval;
    /** indica se la segnalazione va` ripetuta ad intervalli
        regolari o una sola volta */
    private boolean looping;
// Constructors
    public Timer( Timed t, int i )
    {
      this( t, i, true );
    }
    public Timer( Timed t, int i, boolean repeat )
    {
      target = t;
      interval = i;
      looping = repeat;
      setDaemon( true );
    }
// Methods
    public void run()
    {
      do {
        try {
           sleep( interval );
        } catch( InterruptedException e ) {}
        target.tick( this );
      } while( looping );
    }
} // :~ 
/* ------------------- file IlMioProgramma.java ------------------- */
public class IlMioProgramma
   implements Timed
{
   private Timer timer;     // timer per il time-to-live del processo figlio
   private String cmdLine;  // comando da eseguire
   private Process pFiglio; // processo figlio
   /**
    * @param _cmdLine il comando da eseguire
    * @param _timeout tempo massimo per l'esecuzione del comando
    */
   public IlMioProgramma( String _cmdLine, int _timeout ) {
      timer = new Timer( this, _timeout, false );
      cmdLine = _cmdLine;
   }
   /**
    * fa partire il processo figlio ed il timer, se il processo
    * termina prima che il timer sia scaduto, segnala il valore
    * restituito, altrimenti segnala un errore a video.
    */
   public void hopeThisWorks() {
      // fa partire il timer, che segnalera` fra x minuti
      timer.start();
      // fa partire il processo figlio
      System.out.println( "> " + cmdLine );
      pFiglio = Runtime.getRuntime().exec( cmdLine );
      // attende che il processo figlio termini
      try {
        int retVal = pFiglio.waitFor(); // si sospende...
        timer.stop(); /********* okkio che questa e` deprecata! ********/
        System.out.println( "Il processo figlio ha restituito: " + retVal );
      } catch( InterruptedException e ) {
        System.err.println( "Impossibile ottenere il codice di ritorno!" );
        System.exit( 1 );
      }
   }
   /**
    * metodo richiamato allo scadere del timer: indica che il
    * processo figlio non si e` concluso entro il tempo massimo
    * stabilito e che quindi va terminato.
    */
   public void tick( Timer timer ) {
      System.err.println( "Timeout!! Termino il processo figlio..." );
      if( pFiglio != null ) {
        // ...codice per terminare il processo "pFiglio"...
      }
   }
   /**
    * programma di esempio...
    */
   public static void main( String[] args ) {
      // esegue "pippo" ed aspetta massimo 5 sec, dopodiche`
      // stampa un errore a video. Se invece "pippo" termina
      // entro i 5 sec, allora stampa il valore di ritorno.
      new IlMioProgramma( "pippo", 5000 ).hopeThisWorks();
      System.exit( 0 );
   }   
}
*penso* e spero che possa funzionare (ehm... non l'ho provato! :-P)
...se ti "da fastidio" il metodo deprecato, e` abbastanza semplice
inserire un flag booleano "processoTerminato" da impostare a true
dopo il ritorno di waitFor(). In questo modo nel metodo "tick()"
puoi fare un controllo "se il processo e` gia` terminato allora non
fai nulla, altrimenti terminalo..." e non c'e` bisogno di fermare il
timer.
Se invece devi sempre e cmq aspettare i tuoi x minuti prima di dare
un responso a video, allora puoi buttar via il Timer e fare tutto
dentro IlMioProgramma, oppure puoi mantenerlo a patto di:
1. cambiare "setDaemon( true )" in "setDaemon( false )" nel costruttore
   di Timer
2. cancellare, in "HopeThisWorks" tutto quanto segue il Runtime.getRuntime()
3. cambiare il metodo tick() di IlMioProgramma in:
   public void tick( Timer t ) {
     if( pFiglio != null ) {
        try {
           int retVal = pFiglio.exitValue();
           System.out.println( "Il processo figlio ha restituito: " + retVal )
        } catch( Exception e ) {
           System.err.println( "Il processo figlio non ha ancora terminato!" );
           // ...codice x la terminazione forzata di pFiglio...


 di "fare altro" nell'attesa.
[...]
Va benissimo, ora e' chiaro!
Purtroppo non riesco a risponderti on line, il tuo msg. e' lunghissimo e
debbo studiarlo!
Sei stato gentilissimo, spero di poter ricambiare.
Ovviamente appena finisco di leggere e capisco ti faccio sapere cosa penso
di quel che mi hai mandato.
Di nuovo grazie in anticipo (comunque vada...)
W.