gpt4 book ai didi

java - 从 java 执行 C 二进制文件并从进程的输出流中读取

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:52:09 24 4
gpt4 key购买 nike

好的,所以我正在尝试从 java 代码中读取 c 二进制文件的输出,但我无法确定通信 channel 是阻塞的还是非阻塞的。

设置是这样的:

  1. 运行一个java类(A.java)

  2. A.java 使用 Runtime.getRuntime().exec("B.o") 运行一个 c 二进制文件 (B.o)。此时我有 Process 对象(由 Runtime.exec 返回)

  3. A.java 使用 bufferedreader 从 Process 对象的输入流中读取

  4. A.java将从输入流读取的数据输出到文件(output.txt)

B.o 二进制文件使用 printf 函数调用简单地打印随机行。

现在,如果我运行上面的设置,我会完美地接收到 B.o 发送的所有数据。然后为了测试(阻塞/非阻塞的东西),我将 A.java 更改为每次从 B.o 的 Process 对象的输入流读取后 hibernate 5 毫秒。事实证明,现在我没有收到 B.o 发送的 A.java 中的完整数据。这表明正在使用的通信 channel 是非阻塞的(根据我的薄弱理解)。

然后为了确定,我开始查看 java 的源代码,看看我是否正确。到目前为止,我发现了以下内容:

每次调用 Runtime.getRuntime().exec(...) 都会在 ProcessImpl_md.cforkAndExec() 方法中结束.在 ProcessImpl_md.c 中执行命令,创建进程,并设置 PIPES 以进行通信(使用 c 中的管道函数调用)。我在源代码中找不到任何地方将 PIPES 设置为非阻塞模式(如我的代码所示)。我假设 PIPES 默认处于阻塞状态。

我知道这是检查我想检查的内容的一种非常糟糕的方法。我在这里超出了我的深度,我只是在无用地撞头,我想。

任何人都可以指出我正确的方向或告诉我:

  1. 通过 java 运行时 API 创建的进程的 PIPES 是阻塞的还是非阻塞的?

  2. 当我在读取输入流后让 A.java hibernate 时,为什么没有收到所有数据? (假设 PIPE 正在阻塞)

  3. 任何非编程方式(即我不必更改 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);
}
}

请检查我的回答。我的无用问题。

最佳答案

Java与外部程序的通信 channel (一共有三种,一种是从Java到native,另一种是返回)是运行在阻塞还是非阻塞模式,与所有数据能否成功传输没有直接关系跨越每一个。同样,读取请求之间的延迟与是否所有数据都将成功传输没有直接关系,无论在您的 java.lang.Process 的特定实现中阻塞还是非阻塞 I/O。 .

实际上,您尝试探测阻塞与非阻塞进程间 I/O 的努力是徒劳的,因为提供给您的 Java 程序的 I/O 接口(interface)是基于 InputStream 的。和 OutputStream ,它只提供阻塞 I/O。即使非阻塞 I/O 涉及到一些较低级别的实现,我也想不出任何方法让您的程序检测到它。

然而,关于您的具体问题:

Are the PIPES of a process created through java runtime API are blocking or non-blocking?

它们可能是两者之一,但它们更有可能是阻塞的,因为它更符合呈现给 Process 的界面。用户。

When I make A.java sleep after reading from the input stream, why all data is not received? (Assumption being that the PIPE is blocking)

我只能推测,但问题可能出在外部程序中。可能当它的输出缓冲区填满时它会进入 hibernate 状态,并且没有任何事情可以唤醒它。调用 myProcess.getOutputStream().close() 可能会有所帮助如果您的 Java 程序没有向外部程序发送数据。在任何情况下,关闭该流都是一个好主意,一旦您将要写入的所有内容都写入其中。

Any non-programmatic way (i.e. I don't have to change the source code of java and etc!) to figure out if the PIPES of a process are blocking or non-blocking?

可能您可以在 strace 下运行虚拟机或者将 native 调试器连接到它,并以这种方式分析 VM 的行为。如果您打算从 Java 内部执行此操作,那么答案是响亮的“否”。因为 InputStream 的契约(Contract),您的 Java 程序在所有情况下都会看到阻塞行为。和 OutputStream要求它。

关于java - 从 java 执行 C 二进制文件并从进程的输出流中读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28438074/

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