好的,所以我试图从Java代码读取ac二进制的输出,但我无法弄清通信通道是阻塞还是非阻塞。
设置如下:
A.java
运行Java类()
A.javaB.o
使用来运行ac binary()Runtime.getRuntime().exec("B.o")
。至此,我有了Process对象(由Runtime.exec返回)
A.java使用bufferedreader从Process对象的输入流中读取
A.java将从输入流中读取的数据输出到文件(output.txt
)
Bo二进制仅使用printf函数调用来打印随机行。
现在,如果运行上述设置,我将收到所有由B.o
完美发送的数据。然后进行测试(阻塞/非阻塞的东西),A.java
每次从的Process对象的inputstream读取后,我将睡眠更改为5毫秒B.o
。事实证明,现在我没有在A.java
send by中收到完整的数据B.o
。这表明正在使用的通信通道是非阻塞的(根据我的薄弱理解)。
然后只是为了确保,我开始查看java的源代码以查看我是否正确。到目前为止,我发现了以下内容:
每次对的调用都以Runtime.getRuntime().exec(...)
中的forkAndExec()
方法结尾ProcessImpl_md.c
。在ProcessImpl_md.c中,将执行命令,创建过程并设置PIPES以进行通信(使用c中的管道函数调用)。我在源代码中找不到将PIPES设置为非阻塞模式的任何地方(如我的代码所示)。我假设默认情况下,PIPES处于阻止状态。
我知道这是检查我要检查的东西的非常不好的方法。我认为我在这里远远超出了我的深度,我只是无用地敲打头。
谁能指出我正确的方向或告诉我:
通过Java运行时API创建的进程的PIPES是阻塞的还是非阻塞的?
A.java
从输入流读取后进入睡眠状态时,为什么没有收到所有数据?(假设PIPE正在阻塞)
有任何非编程方式(例如,我不必更改Java等的源代码!)来确定进程的PIPES是阻塞还是非阻塞?
谢谢你。
编辑:(添加代码)
以下不是实际的(甚至不是可编译的)代码,但是它显示了我正在尝试执行的操作。
“ Bo”的来源:
#include <stdio.h>
void main(int argc, char*argv[]){
int a = 0;
for(; a<9000000; a++){
printf("%s", argv[1]);
}
}
“ A.java”的来源:
<java imports>
public class A{
public static void main(String[] args) throws Exception{
Process p = Runtime.getRuntime().exec("./B.o");
BufferedReader br = new
BufferedReader(new InputStreamReader(p.getInputStream()));
int a = 0;
while(br.readLine() != null){
a++;
Thread.sleep(5);//data missed if this line not commented out
}
br.close();
System.out.println(a);
}
}
请检查我的答案。我的无聊问题。
Java和外部程序之间的通信通道(共有三个,一个是从Java到本机,另一个是返回)在阻塞模式还是非阻塞模式下运行,与是否所有数据都将成功地在每个数据上传输没有直接关系。同样地,读取请求之间的延迟并不是是否所有数据将被发送成功直接相关的,无论阻塞与非阻塞I / O在具体实现的java.lang.Process
。
确实,探索阻塞与非阻塞进程间I / O的工作是徒劳的,因为提供给Java程序的I / O接口基于InputStream
和OutputStream
,而I和O仅提供阻塞I / O。即使在实现的某个较低级别上涉及到非阻塞I / O,我也想不出任何方式让您的程序检测到它。
关于您的特定问题,但是:
通过Java运行时API创建的进程的PIPES是阻塞的还是非阻塞的?
它们可以是两者之一,但是它们更有可能被阻塞,因为这更好地匹配了呈现给Process
用户的界面。
从输入流读取后使A.java休眠时,为什么未接收到所有数据?(假设PIPE正在阻塞)
我只能推测,但是问题很可能在外部程序中。当输出缓冲区填满时,它可能会进入睡眠状态,并且什么也没有唤醒它。myProcess.getOutputStream().close()
如果您的Java程序未将数据发送到外部程序,则可能有助于调用。在任何情况下,一旦写入所有内容,关闭该流都是一个好主意。
有任何非编程方式(例如,我不必更改Java等的源代码!)来确定进程的PIPES是阻塞还是非阻塞?
可能您可以在其下运行VMstrace
或将本机调试器连接到该VM,然后以这种方式分析VM的行为。如果您打算从Java内部执行此操作,那么答案是肯定的“否”。您的Java程序在所有情况下都将看到阻塞行为,因为它们的合同InputStream
并OutputStream
要求这样做。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句