我有一个程序,我使用命名管道与外部可执行文件共享信息:
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
命令的输出,但问题似乎不存在。
任何人都知道解决方法/修复此问题吗?
答案 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;
}