Java process.getInputStream() 没有啥可读的,死锁子
Posted
技术标签:
【中文标题】Java process.getInputStream() 没有啥可读的,死锁子【英文标题】:Java process.getInputStream() has nothing to read, deadlocks childJava process.getInputStream() 没有什么可读的,死锁子 【发布时间】:2011-04-14 23:43:13 【问题描述】:我遇到了一些进程包装问题,它只发生在 Windows XP 中。这段代码在 Windows 7 中完美运行。我真的很困惑为什么 XP 中的流是空的。我也尝试过使用 Process.Exec() 的 String[] 版本,它没有任何区别。
我正在使用以下类来读取进程的 STDOUT 和 STDERR(每个流的实例):
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");
我在这里使用它:
Process p = Runtime.getRuntime().exec("test.exe");
Queue<String> q = new LinkedList<String>();
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());
有人有什么想法吗?谢谢!
编辑:添加同步
编辑:就像更新一样,父流读取器的读取操作被阻止。如果我使用任务管理器杀死子进程,它们会从流的关闭中读取 null。
【问题讨论】:
+1 提出了一个很好的详细问题,表明您已经考虑了这里可能出现的潜在问题。 坐在这里上网搜索答案后,我偶然发现了这个问题。我还没有找到解决方案,只有一种解决方法,但至少我已经启动并运行了。我传递给程序的参数之一导致它挂起。我取出了参数,这对于我正在尝试做的事情并不是最佳的,但程序不再挂起。同样的参数也适用于我的 Win7 机器,所以我什至不认为这是其中的一部分。哦,好的,谢谢你的帮助! 你删除了什么样的参数?我在 Java 中遇到了一些奇怪而愚蠢的死锁问题(都有一个共同点:从 System.in 中读取) 【参考方案1】:你需要使用线程安全的数据结构;我不认为 LinkedList 是线程安全的。
【讨论】:
我已经更新了要同步的代码。它仍然有同样的问题。 :\【参考方案2】:让我印象深刻的一个错误是LinkedList
is not synchronized,但您正试图在 2 个线程中写入它。
要记住的另一件事是Process.getInputStream()
返回进程的stdout
流,因此您应该将当前名为stdin
的变量重命名为stdout
以防止混淆。
【讨论】:
是的,我对“stdin”的使用感到困惑。从 Java 程序的角度来看,它是一个输入流,但从 Process 的角度来看,它是标准输出。 我已将标准输入更改为标准输出并添加同步。【参考方案3】:Vista 之前的 Windows 操作系统中存在已知错误,加载 DLL 会导致 IO 挂起。
例如见http://weblogs.java.net/blog/kohsuke/archive/2009/09/28/reading-stdin-may-cause-your-jvm-hang和https://connect.microsoft.com/VisualStudio/feedback/details/94701/loadlibrary-deadlocks-with-a-pipe-read
我不确定这是否是您遇到的问题,但它可能是相关的。
另外,我隐约记得从非控制台 Windows 应用程序获取有效标准输入和标准输出的一些问题。如果您对“test.jar”的调用使用的是“javaw”而不是“java”,那么这也可能是导致问题的原因。
【讨论】:
哦,我只是以test.jar为例。不过,很高兴知道这一点。 阅读 System.in 通常是个问题。我对这个问题的回答中有更多指向 SUN-ug 报告的链接:***.com/questions/3836780/…【参考方案4】:由于一些原生平台只为标准输入输出流提供有限的缓冲区大小,未能及时写入子进程的输入流或读取输出流可能会导致子进程阻塞,甚至死锁。
【讨论】:
以上是关于Java process.getInputStream() 没有啥可读的,死锁子的主要内容,如果未能解决你的问题,请参考以下文章