Java process.getInputStream() 没有任何内容可读取,子进程死锁

发布于 2024-09-24 09:39:54 字数 1324 浏览 1 评论 0原文

我在某些进程包装方面遇到问题,并且该问题仅发生在 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());
    }
}

有人有任何想法吗?谢谢!

编辑:添加同步

编辑:就像更新一样,父流读取器的读取操作被阻止。如果我使用任务管理器终止子进程,它们会从流的关闭中读取空值。

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

ヅ她的身影、若隐若现 2024-10-01 09:39:54

你需要使用线程安全的数据结构;我不认为 LinkedList 是线程安全的。

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

荭秂 2024-10-01 09:39:54

令我震惊的一个错误是 LinkedList< /code> 未同步,但您尝试在 2 个线程中写入它。

另一件需要记住的事情是 Process.getInputStream() 返回进程的 stdout 流,因此您应该重命名当前称为 stdin 的变量到 stdout 以防止混淆。

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.

时光匆匆的小流年 2024-10-01 09:39:54

Vista 之前的 Windows 操作系统中存在已知错误,加载 DLL 可能会导致 IO 挂起。

例如,请参见 http://weblogs.java.net/blog/kohsuke/archive/2009/09/28/reading-stdin-may-cause-your-jvm-hanghttps://connect.microsoft.com/VisualStudio/feedback/details/94701/ loadlibrary-deadlocks-with-a-pipe-read

我不确定这是否是您遇到的情况,但它可能是相关的。

另外,我隐约记得从非控制台 Windows 应用程序获取有效的标准输入和标准输出的一些问题。如果您对“test.jar”的调用使用“javaw”而不是“java”,那么这也可能是导致您的问题的原因。

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.

oО清风挽发oО 2024-10-01 09:39:54

由于某些本机平台只为标准输入输出流提供有限的缓冲区大小,因此未能及时写入子进程的输入流或读取子进程的输出流可能会导致子进程阻塞,甚至死锁。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文