简体   繁体   中英

Stream not closing appropriately while using named pipes in Java/Linux

I have a program where I use named pipes to share info with an external executable:

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

When I execute this, the program hangs waiting for cat to finish. It seems that cat has not 'realized' that the fifo was closed.

I tried running $> touch /tmp/myfifo on the terminal, and it worked to 'unhang' the process and it finishing properly; but when I added code to run this within my program, it would remain hanging:

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

The process will still hang waiting for cat to finish. I'm not sure what to do now.

NOTE - I have already added code to consume the output of the cat command, but the problem does not seem to be there.

Anyone know a workaround/fix for this?

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.you need to consume the output like print it on stdout something or file

try something like this

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM