Java process.getInputStream() has nothing to read, deadlocks child

霸气de小男生 提交于 2019-12-22 04:04:24

问题


I am having an issue with some process wrapping, and it's only occurring in Windows XP. This code works perfectly in Windows 7. I'm really stumped as to why the streams are empty in XP. I've also tried using the String[] version of Process.Exec() and it made no difference.

I am using the following class to read from the process' STDOUT and STDERR (an instance for each stream):


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

And I use it here:


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

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

Anyone have any ideas? Thanks!

Edit: Added synchronization

Edit: Just as an update, the parent stream readers are blocked on their read operation. If I kill the child processes, with the task manager, they read in the null from the closing of the stream.


回答1:


You need to use a threadsafe data structure; I don't think LinkedList is threadsafe.




回答2:


One mistake that strikes me is that LinkedList is not synchronized, but you're trying to write to it in 2 threads.

Another thing to keep in mind is Process.getInputStream() returns the stdout stream of the process, so you should rename the variable currently called stdin to stdout to prevent confusion.




回答3:


There are known bugs in pre-Vista Windows operating systems where loading DLLs can cause a hang in IO.

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

I'm not sure if this is what you are running in to, but it may be related.

Also, I vaguely recall some issues in getting a valid stdin and stdout from non-console windows applications. If your call to 'test.jar' is using 'javaw' rather than 'java', then this could be the cause of your problem, too.




回答4:


Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.



来源:https://stackoverflow.com/questions/3756899/java-process-getinputstream-has-nothing-to-read-deadlocks-child

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!