2010-09-21 18 views
8

Tengo un problema con algunos procesos de ajuste, y solo ocurre en Windows XP. Este código funciona perfectamente en Windows 7. Estoy realmente perplejo sobre por qué las transmisiones están vacías en XP. También intenté usar la versión String [] de Process.Exec() y no importó nada.Java process.getInputStream() no tiene nada que leer, deadlocks child

estoy usando la siguiente clase para leer desde el proceso de stdout y stderr (una instancia para cada flujo):


import java.util.*; 
import java.io.*; 

public class ThreadedStreamReader extends Thread{ 
InputStream in; 
Queue messageQueue; 

public ThreadedStreamReader(InputStream s, Queue q) 
{ 
    in = s; 
    messageQueue = q; 
} 

public void run() 
{ 
    try 
    { 
    BufferedReader r = new BufferedReader(new InputStreamReader(in)); 
    String line = null; 
    while((line = r.readLine()) != null) 
    { 
    synchronized(messageQueue) 
    { 
    messageQueue.add(line); 
    } 
    } 

    }catch(Exception e) 
    { 
    System.err.println("Bad things happened while reading from a stream"); 
    } 
} 
} 

y lo uso aquí:


Process p = Runtime.getRuntime().exec("test.exe"); 
Queue&ltString> q = new LinkedList&ltString>(); 

ThreadedStreamReader stdout = new ThreadedStreamReader(p.getInputStream(), q); 
ThreadedStreamReader stderr = new ThreadedStreamReader(p.getErrorStream(), q); 

stdout.start(); 
stderr.start(); 

while(true) 
{ 
    while(q.size() > 0) 
    { 
     System.out.println(q.remove()); 
    } 
} 

Alguien tiene alguna ideas? ¡Gracias!

Editar: Se ha añadido la sincronización

edición: Del mismo modo que una actualización, los lectores de flujo padres están bloqueados en su operación de lectura. Si elimino los procesos hijos, con el administrador de tareas, ellos leen el nulo desde el cierre de la transmisión.

+1

+1 por tener una buena pregunta detallada que demuestre que ha pensado en los posibles problemas que podrían surgir aquí. –

+1

Después de sentarme aquí revisando las respuestas por Internet, me encontré al azar con el problema. No he resuelto la solución, solo una solución alternativa, pero al menos estoy en funcionamiento. Uno de los parámetros que estaba pasando al programa lo colgó. Saqué el parámetro, que no era óptimo para lo que estoy tratando de hacer, pero el programa ya no cuelga. Ese mismo parámetro funcionó en mi caja Win7, así que ni siquiera pensé que era parte de eso. Oh, bueno, gracias por la ayuda! – Banana

+0

¿Qué tipo de parámetro eliminaste? Tuve algunos problemas extraños y tontos con interbloqueos en Java (todos tenían algo en común: lectura de System.in) –

Respuesta

1

Debe utilizar una estructura de datos segura para la rosca; No creo que LinkedList sea seguro.

+0

He actualizado el código para sincronizar. Todavía tiene el mismo problema. : \ – Banana

1

Un error que me sorprende es que LinkedList is not synchronized, pero está tratando de escribir en 2 hilos.

Otra cosa a tener en cuenta es Process.getInputStream()stdout devuelve la corriente del proceso, por lo que debe cambiar el nombre de la variable actualmente llamada stdin a stdout para evitar confusiones.

+0

Sí, me confundí con el uso de "stdin". Desde el punto de vista de su programa Java, se trata de un flujo de entrada, pero desde el punto de vista del proceso es estándar. –

+0

He cambiado stdin a stdout junto con agregar sincronización. – Banana

1

Se conocen errores en los sistemas operativos Windows anteriores a la Vista donde cargar archivos DLL puede causar un bloqueo en IO.

p. Ej. ver http://weblogs.java.net/blog/kohsuke/archive/2009/09/28/reading-stdin-may-cause-your-jvm-hang y https://connect.microsoft.com/VisualStudio/feedback/details/94701/loadlibrary-deadlocks-with-a-pipe-read

No estoy seguro de si esto es a lo que se está ejecutando, pero puede estar relacionado.

Además, recuerdo vagamente algunos problemas al obtener un stdin y stdout válidos de aplicaciones de Windows que no son de consola. Si su llamada a 'test.jar' usa 'javaw' en lugar de 'java', esta podría ser la causa de su problema también.

+1

Oh, acabo de utilizar test.jar como ejemplo. Eso es bueno saber, sin embargo. – Banana

+0

Reading System.in suele ser un problema. Más enlaces a informes SUN-ug en mi respuesta a esta pregunta: http://stackoverflow.com/questions/3836780/serversocket-blocked-by-thread-seeking-input-from-console/4078869#4078869 –

1

Dado que algunas plataformas nativas solo proporcionan un tamaño de búfer limitado para flujos de entrada y salida estándar, si no se escribe rápidamente la secuencia de entrada o se lee el flujo de salida del subproceso puede provocar el bloqueo del subproceso e incluso un bloqueo.

Cuestiones relacionadas