在Java / Linux中使用命名管道时,流未正确关闭

时间:2015-08-06 09:45:24

标签: java linux process named-pipes

我有一个程序,我使用命名管道与外部可执行文件共享信息:

Process p = Runtime.getRuntime().exec("mkfifo /tmp/myfifo");
p.waitFor();
Process cat = Runtime.getRuntime().exec("cat /tmp/myfifo");
BufferedWriter fifo = new BufferedWriter(
                new OutputStreamWriter(new FileOutputStream("/tmp/myfifo")));
fifo.write("Hello!\n");
fifo.close();
cat.waitFor();

执行此操作时,程序将等待cat完成。猫似乎还没有“意识到”这个号码被关闭了。

我尝试在终端上运行$> touch /tmp/myfifo,它努力“解开”流程并正常完成;但是当我在我的程序中添加代码来运行它时,它仍然会挂起:

fifo.close();
Process touch = Runtime.getRuntime().exec("touch /tmp/myfifo");
touch.waitFor();
cat.waitFor();

该过程仍将等待cat完成。我不知道现在该做什么。

注意 - 我已经添加了代码来使用cat命令的输出,但问题似乎不存在。

任何人都知道解决方法/修复此问题吗?

1 个答案:

答案 0 :(得分:1)

  

某些本机平台仅为标准提供有限的缓冲区大小   输入和输出流,无法及时写入输入流   或者读取子进程的输出流可能会导致子进程   阻止,甚至死锁。你需要消耗输出,比如在stdout上打印它或文件

尝试这样的事情

 Process cat = Runtime.getRuntime().exec("cat /tmp/myfifo");
 new Thread(new Reader(cat.getErrorStream(), System.err)).start();
 new Thread(new Reader(cat.getInputStream(), System.out)).start();
 int returnCode = cat.waitFor();
 System.out.println("Return code = " + returnCode);


class Reader implements Runnable
{
public Reader (InputStream istrm, OutputStream ostrm) {
      this.istrm = istrm;
      this.ostrm = ostrm;
  }
  public void run() {
      try
      {
          final byte[] buffer = new byte[1024];
          for (int length = 0; (length = istrm.read(buffer)) != -1; )
          {
              ostrm.write(buffer, 0, length);
          }
      }
      catch (Exception e)
      {
          e.printStackTrace();
      }
  }
  private final OutputStream ostrm;
  private final InputStream istrm;
}