gpt4 book ai didi

java - 了解 I/O 阻塞

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:40:05 25 4
gpt4 key购买 nike

我有一个二进制 linux 可执行文件,它在标准输出中打印一些字节。我这样使用来自 Java 应用程序的这些字节:

String[] cmd;
Process p = Runtime.getRuntime().exec(cmd);
InputStream is = p.getInputStream();
int r = is.read();
while(r != -1){
System.out.println(r);
r = is.read(); //1
}

但是在工作一段时间后,//1 将永远阻塞 I/O(死锁)。我创建了线程转储并注意到

"pool-2-thread-1@627" prio=5 tid=0xd nid=NA runnable
java.lang.Thread.State: RUNNABLE
at java.io.FileInputStream.readBytes(FileInputStream.java:-1)
at java.io.FileInputStream.read(FileInputStream.java:255)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:284)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
- locked <0x2c0> (a java.lang.UNIXProcess$ProcessPipeInputStream)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)

它被锁定在一个本地方法上

private native int readBytes(byte[] var1, int var2, int var3) throws IOException;

此方法被永久阻止的可能原因是什么?也许这是特定于平台的。我正在使用 Ubuntu 16.04

最佳答案

您不需要查看标准库的内部方法来寻找答案。 The docs of InputStream.read()部分指定

If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

也许混淆的关键点是“检测到流的结尾”的意思。这并不意味着现在没有更多的字节可供读取——这与该方法在数据可用之前阻塞的规范不一致,并且实际上它在许多情况下效果不佳情况。相反,当系统收到某种信号,表明不再有字节可用时,流的结尾将被检测到。永远。通常,这意味着流已在源端关闭,并且在目标端从流中排出所有字节。

在您的特定情况下,如果外部进程继续运行,没有向其标准输出进一步写入任何内容,但也没有关闭其标准输出,那么 Java(或 native 使用者)将永远不会查看该进程输出的流结束。

关于java - 了解 I/O 阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43805578/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com