2010-09-21 10 views
8

Ich habe ein Problem mit einigen Prozess-Wrapping, und es tritt nur in Windows XP. Dieser Code funktioniert perfekt in Windows 7. Ich bin wirklich ratlos, warum die Streams in XP leer sind. Ich habe auch versucht, die String [] Version von Process.Exec() zu verwenden, und es machte keinen Unterschied.Java process.getInputStream() hat nichts zu lesen, Deadlocks Kind

ich die folgende Klasse verwenden aus dem Prozess STDOUT und STDERR (für jeden Strom eine Instanz) zu lesen:


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"); 
    } 
} 
} 

Und ich benutze es hier:


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()); 
    } 
} 

Wer noch keine Ideen? Vielen Dank!

Edit: Hinzugefügt Synchronisation

Edit: Gerade als Update werden die Eltern Stream Leser blockiert auf ihre Leseoperation. Wenn ich die untergeordneten Prozesse mit dem Task-Manager abbringe, lesen sie die Null vom Schließen des Streams.

+1

+1 für eine gute detaillierte Frage, die zeigt, dass Sie die möglichen Probleme, die hier entstehen könnten, durchdacht haben. –

+1

Nachdem ich hier im Internet nach Antworten gesucht habe, stolperte ich zufällig über das Problem. Ich habe die Lösung nicht gefunden, nur ein Workaround, aber zumindest bin ich am Laufen. Einer der Parameter, die ich an das Programm übergeben habe, ließ es hängen. Ich nahm den Parameter heraus, der für das, was ich versuche, nicht optimal war, aber das Programm hängt nicht mehr. Derselbe Parameter funktionierte auf meiner Win7-Box, also glaubte ich nicht einmal, dass das ein Teil davon war. Na gut, danke für die Hilfe! – Banana

+0

Welche Art von Parameter haben Sie entfernt? Ich hatte einige seltsame und dumme Probleme mit Deadlocks in Java (alle hatten eines gemeinsam: Lesen von System.in) –

Antwort

1

Sie müssen eine threadsafe Datenstruktur verwenden; Ich glaube nicht, dass LinkedList threadsicher ist.

+0

Ich habe den Code aktualisiert, um zu synchronisieren. Es hat immer noch das gleiche Problem. : \ – Banana

1

Ein Fehler, der mir auffällt ist, dass LinkedList is not synchronized, aber Sie versuchen, es in 2 Threads zu schreiben.

Eine andere Sache im Auge zu behalten ist Process.getInputStream() kehrt der stdout Strom des Prozesses, so sollten Sie die Variable umbenennen derzeit stdin-stdout genannt Verwirrung zu vermeiden.

+0

yeah, ich wurde durch die Verwendung von "stdin" verwirrt. Aus der Sicht Ihres Java-Programms ist es ein Eingabestream, aber aus der Sicht des Prozesses ist es stdout. –

+0

Ich habe stdin zu stdout geändert und Synchronisierung hinzugefügt. – Banana

1

Es gibt bekannte Fehler in Windows-Betriebssystemen vor Vista, bei denen das Laden von DLLs zu einem Hängenbleiben in IO führen kann.

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

Ich bin mir nicht sicher, ob das ist, was Sie laufen, aber es kann verwandt sein.

Außerdem erinnere ich mich vage an einige Probleme beim Abrufen eines gültigen stdin und stdout aus nicht-Konsole Windows-Anwendungen. Wenn Ihr Aufruf von 'test.jar' 'javaw' anstelle von 'java' verwendet, könnte dies auch die Ursache für Ihr Problem sein.

+1

Oh, ich habe gerade test.jar als Beispiel benutzt. Das ist aber gut zu wissen. – Banana

+0

Das Lesen von System.in ist oft ein Problem. Weitere Links zu SUN-ug-Berichten in meiner Antwort auf diese Frage: http://stackoverflow.com/questions/3836780/serversocket-blocked-by-thread-seeking-input-from-console/4078869#4078869 –

1

Da einige native Plattformen nur eine begrenzte Puffergröße für Standardeingabe- und -ausgabeströme bieten, kann der Fehler beim sofortigen Schreiben des Eingabestreams oder beim Lesen des Ausgabestreams des Unterprozesses zum Blockieren des Unterprozesses und sogar zum Deadlock führen.

Verwandte Themen