Process.waitFor() nunca regresa

Resuelto user590444 asked hace 13 años • 12 respuestas
Process process = Runtime.getRuntime().exec("tasklist");
BufferedReader reader = 
    new BufferedReader(new InputStreamReader(process.getInputStream()));
process.waitFor();
user590444 avatar Mar 30 '11 15:03 user590444
Aceptado

Hay muchas razones por las que waitFor()no regresa.

Pero normalmente todo se reduce al hecho de que el comando ejecutado no se cierra.

Esto, nuevamente, puede deberse a muchas razones.

Una razón común es que el proceso produce algún resultado y no se lee en las secuencias apropiadas. Esto significa que el proceso se bloquea tan pronto como el búfer está lleno y espera a que su proceso continúe leyendo. Su proceso, a su vez, espera a que finalice el otro proceso (lo cual no sucederá porque espera a su proceso,...). Ésta es una situación clásica de punto muerto.

Debe leer continuamente el flujo de entrada del proceso para asegurarse de que no se bloquee.

Hay un buen artículo que explica todos los errores Runtime.exec()y muestra cómo solucionarlos llamado "Cuando Runtime.exec() no funciona" (sí, el artículo es del año 2000, ¡pero el contenido aún se aplica!)

Joachim Sauer avatar Mar 30 '2011 08:03 Joachim Sauer

Parece que no estás leyendo el resultado antes de esperar a que finalice. Esto está bien sólo si la salida no llena el búfer. Si es así, esperará hasta que lea el resultado, catch-22.

Quizás tengas algunos errores que no estás leyendo. Esto haría que la aplicación se detuviera y esperara para siempre. Una forma sencilla de solucionar este problema es redirigir los errores a la salida normal.

ProcessBuilder pb = new ProcessBuilder("tasklist");
pb.redirectErrorStream(true);
Process process = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null)
    System.out.println("tasklist: " + line);
process.waitFor();
Peter Lawrey avatar Mar 30 '2011 08:03 Peter Lawrey

También del documento Java:

java.lang

Proceso de clase

Debido a que algunas plataformas nativas solo proporcionan un tamaño de búfer limitado para los flujos de entrada y salida estándar, no escribir rápidamente el flujo de entrada o leer el flujo de salida del subproceso puede provocar que el subproceso se bloquee e incluso se bloquee.

No borrar el búfer del flujo de entrada (que canaliza al flujo de salida del subproceso) del proceso puede provocar el bloqueo del subproceso.

Prueba esto:

Process process = Runtime.getRuntime().exec("tasklist");
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((reader.readLine()) != null) {}
process.waitFor();
RollingBoy avatar Mar 30 '2011 08:03 RollingBoy

Me gustaría agregar algo a las respuestas anteriores, pero como no tengo representante para comentar, simplemente agregaré una respuesta. Esto está dirigido a usuarios de Android que programan en Java.

Según la publicación de RollingBoy, este código casi funcionó para mí:

Process process = Runtime.getRuntime().exec("tasklist");
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((reader.readLine()) != null) {}
process.waitFor();

En mi caso, waitFor() no se liberó porque estaba ejecutando una declaración sin retorno ("ip adddr flush eth0"). Una manera fácil de solucionar este problema es simplemente asegurarse de devolver siempre algo en su estado de cuenta. Para mí, eso significó ejecutar lo siguiente: "ip adddr flush eth0 && echo done". Puede leer el búfer todo el día, pero si nunca se devuelve nada, su hilo nunca liberará su espera.

¡Espero que ayude a alguien!

Slopes avatar May 20 '2015 20:05 Slopes

Hay varias posibilidades:

  1. No ha consumido todo el resultado del proceso stdout.
  2. No ha consumido todo el resultado del proceso stderr.
  3. El proceso está esperando su opinión y usted no la ha proporcionado o no ha cerrado el proceso stdin.
  4. El proceso gira en un bucle cerrado.
user207421 avatar Apr 20 '2016 10:04 user207421