【发布时间】:2015-02-10 17:31:35
【问题描述】:
好的,所以我试图从 java 代码中读取 c 二进制文件的输出,但我无法确定通信通道是阻塞还是非阻塞。
设置是这样的:
一个 java 类 (
A.java) 正在运行A.java 使用
Runtime.getRuntime().exec("B.o")运行 c 二进制文件 (B.o)。此时我有了 Process 对象(由 Runtime.exec 返回)A.java 使用缓冲读取器从 Process 对象的输入流中读取数据
A.java 将从输入流中读取的数据输出到文件 (
output.txt)
B.o 二进制文件使用 printf 函数调用简单地打印随机行。
现在,如果我运行上述设置,我将完美接收B.o 发送的所有数据。然后为了测试(阻塞/非阻塞的东西),我将A.java 更改为在每次读取B.o 的 Process 对象的输入流后休眠 5 毫秒。事实证明,现在我没有收到由B.o 发送的A.java 中的完整数据。这表明正在使用的通信通道是非阻塞的(根据我的薄弱理解)。
然后为了确定,我开始查看java的源代码,看看我是否正确。到目前为止,我发现了以下内容:
对Runtime.getRuntime().exec(...) 的每次调用都以ProcessImpl_md.c 中的forkAndExec() 方法结束。在 ProcessImpl_md.c 中执行命令,创建进程,并设置 PIPES 进行通信(使用 c 中的管道函数调用)。我在源代码中找不到将 PIPES 设置为非阻塞模式的任何地方(如我的代码所示)。我假设 PIPES 默认是阻塞的。
我知道这是检查我要检查的内容的一种非常糟糕的方法。我在这里超出了我的深度,我想我只是在无用地敲打头。
谁能指出我正确的方向或告诉我:
通过 java 运行时 API 创建的进程的 PIPES 是阻塞的还是非阻塞的?
当我从输入流读取后使
A.java睡眠时,为什么没有收到所有数据? (假设管道阻塞)任何非编程方式(即我不必更改 java 等的源代码!)来确定进程的 PIPES 是阻塞还是非阻塞?
谢谢。
编辑:(添加代码)
以下不是实际的(甚至是可编译的)代码,但它显示了我正在尝试做的事情。
“B.o”的来源:
#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);
}
}
请检查我的答案。我的无用问题。
【问题讨论】:
-
我会避免对可执行文件使用 *.o 扩展名(您的
B.o)。该扩展名通常用于对象文件。 -
睡眠不应改变您从包装在 BufferedReader 中的 InputStream 获得的输入。 “非阻塞”读取并不意味着您跳过输入以获取管道中最近的写入。也就是说,尚不清楚您为什么要观察跳过的数据。能贴出相关代码吗?
-
真的是“随机”行吗?你永远不会知道是否有一些失踪。
-
@Tim Cas。谢谢。会记住这一点。
-
@Andy Thomas。我认为问题实际上出在 B.o 二进制文件正在写入的管道的写入端。你怎么看?感谢您的回复。