2011-04-27 21 views
9

tengo un procesoComprobar si el proceso se ejecuta en Windows/Linux

Runtime rt = Runtime.getRuntime() ; 
Process p = rt.exec(filebase+port+"/hlds.exe +ip "+ip+" +maxplayers "+players+ " -game cstrike -console +port "+port+" -nojoy -noipx -heapsize 250000 +map de_dust2 +servercfgfile server.cfg +lservercfgfile +mapcyclefile mapcycle.txt +motdfile motd.txt +logsdir logs -zone 2048",null, new File(filebase+port)) ; 

quiero mantener un control sobre este proceso si su funcionamiento o se ha estrellado en caso de accidente desee reiniciarlo, este proceso puede tener múltiples instancias disponibles dependiendo del puerto

¿Puedo rastrear esto tanto en Linux como en Windows? Lea algunos artículos, pero este 1 es un poco diferente, ya que implica varias ocurrencias y tiene que verificar algún proceso en particular solo

Respuesta

2

Puede hacer un p.waitFor() para que el hilo que ejecutó la instrucción espere hasta que el proceso se complete. Luego puede hacer la lógica de limpieza/reinicio justo después, ya que ese código se ejecutará cuando el proceso fallezca. Sin embargo, no estoy seguro de cómo funcionaría si el proceso se detiene en lugar de morir, pero podría valer la pena intentarlo. Por cierto, recomendaría usar Java Service Wrapper y supervisord en su caso si esto es algo que va a hacer en producción.

+0

en este caso yo debería crear un nuevo cada hilo estoy empezando un nuevo proceso ? y seguir sondeando en el mismo hilo? – Varun

0

Java 5 y tienen una forma de manejar esto usando java.util.concurrent.Future.

A Future representa el resultado de un cálculo asincrónico. Se proporcionan métodos para verificar si el cálculo está completo, para esperar su finalización y para recuperar el resultado del cálculo. El resultado solo se puede recuperar usando el método get cuando el cálculo se ha completado, bloqueándolo si es necesario hasta que esté listo. La cancelación se realiza mediante el método cancelar. Se proporcionan métodos adicionales para determinar si la tarea se completó normalmente o si se canceló. Una vez que se ha completado un cálculo, el cálculo no se puede cancelar. Si desea utilizar un futuro por el bien de la cancelación, pero no proporciona un resultado utilizable, puede declarar los tipos del formulario futuro y devolver nulo como resultado de la tarea subyacente.

+1

no entiendo el método ... cualquier explicación clara, por favor :) – Varun

+0

En Java 5, se agregó un nuevo y variado paquete potente, java.util.concurrent. Hace que la gestión de subprocesos sea mucho más fácil al proporcionar clases que saben cómo trabajar con diferentes casos de uso de manera eficiente y de manera segura. Si necesita implementar un productor/consumidor, o una cola de bloqueo, o una tarea programada, la mayor parte del trabajo duro está hecho para usted.La clase Future se usa para rastrear el estado de un hilo, e incluso obtener un valor de retorno cuando existe. Parece que usar este paquete, y Future en particular, te ahorraría mucho trabajo. –

+1

¿Cuál es la conexión entre 'Process' y' Future'? –

0
public class ProcessEndNotifier extends Thread 
{ 
    Process process; 
    MyClass classThatNeedsToBeNotified; 

    public ProcessEndNotifier(MyClass classThatNeedsToBeNotified, Process process) 
    { 
     this.process = process; 
     this.classThatNeedsToBeNotified = classThatNeedsToBeNotified; 
    } 

    @Override 
    public void run() 
    { 
     try { 
      process.waitFor(); 
     } 
     catch (InterruptedException e) { 
      classThatNeedsToBeNotified.processEnded(); 
     } 
     classThatNeedsToBeNotified.processEnded(); 
    } 
} 

ya se puede saber si un proceso en el funcionamiento de la siguiente manera:

public class MyClass 
{ 
    boolean isProcessRunning;  

    public static void main(String[]args) 
    { 
     Process process = Runtime.getRuntime().exec("foo -bar"); 
     isProcessRunning = true; 
     new ProcessEndNotifier(this, process).run(); 
    } 

    public void processEnded() 
    { 
     isProcessRunning = false; 
     // Or just do stuff here! 
    } 
} 
1

A partir de Java 8 se puede hacer:

process.isAlive()

+1

Si bien esto podría responder teóricamente a la pregunta, [sería preferible] (// meta.stackoverflow.com/q/8259) incluir aquí las partes esenciales de la respuesta y proporcionar el enlace de referencia. –

0

Para el código pre Java 8, estoy usando la reflexión con una reserva para capturar IllegalThreadStateException. La reflexión solo funcionará en instancias de ProcessImpl, pero como eso es lo que devuelve ProcessBuilder, generalmente es el caso para mí.

public static boolean isProcessIsAlive(@Nullable Process process) { 
    if (process == null) { 
     return false; 
    } 
    // XXX replace with Process.isAlive() in Java 8 
    try { 
     Field field; 
     field = process.getClass().getDeclaredField("handle"); 
     field.setAccessible(true); 
     long handle = (long) field.get(process); 
     field = process.getClass().getDeclaredField("STILL_ACTIVE"); 
     field.setAccessible(true); 
     int stillActive = (int) field.get(process); 
     Method method; 
     method = process.getClass().getDeclaredMethod("getExitCodeProcess", long.class); 
     method.setAccessible(true); 
     int exitCode = (int) method.invoke(process, handle); 
     return exitCode == stillActive; 
    } catch (Exception e) { 
     // Reflection failed, use the backup solution 
    } 
    try { 
     process.exitValue(); 
     return false; 
    } catch (IllegalThreadStateException e) { 
     return true; 
    } 
} 
0

en Java 9, puede utilizar el método isAlive() para comprobar si un proceso se stil funcionando de esta manera:

Runtime rt = Runtime.getRuntime() ; 
Process p = rt.exec(filebase+port+"/hlds.exe +ip "+ip+" +maxplayers "+players+ " -game cstrike -console +port "+port+" -nojoy -noipx -heapsize 250000 +map de_dust2 +servercfgfile server.cfg +lservercfgfile +mapcyclefile mapcycle.txt +motdfile motd.txt +logsdir logs -zone 2048",null, new File(filebase+port)) ; 
boolean isRunning = p.toHandle.isAlive(); 
Cuestiones relacionadas