【发布时间】:2021-07-14 07:19:06
【问题描述】:
我用 C++ 编写了一个使用多线程的程序。使用 bash 脚本或类似的东西调用这个程序没问题,一切正常。现在我想用 Java 调用这个程序。这是我尝试过的 Java 代码示例:
Process v2j = new ProcessBuilder("./src/main/cpp/vcd_converter",
"-vcd", vcdfilePath, "-out", logfilePath).start();
InputStream is = v2j.getInputStream();
InputStream es = v2j.getErrorStream();
for(int i = 0; i < is.available(); i++) {
System.out.println("Input: " + br.readLine());
}
for(int i = 0; i < es.available(); i++) {
System.out.println("Error: " + ebr.readLine());
}
v2j.waitFor();
因此,如果我运行此代码,将发生以下情况:waitFor() 指令似乎不会真正等待“所有”线程,也许它只会等待一个。但是,java 程序执行时出错,因为它找不到由 C++ 程序生成的文件。所以waitFor() 不要等到我的 c++ 程序完成并生成文件。
输出也很奇怪。我只从std::cout 得到一个输出。这是一个例子:
std::cout << out_folder_path << "\n" << vcd_filename << "\n";
std::cout << std::flush;
这将只打印out_folder_path 输出。一个问题是:在std::cout 部分我什至不使用多线程。程序中的所有其他std::cout 也不打印。
所以我的问题是:我如何才能真正等待所有线程?我怎样才能得到我的程序的真正输出?
【问题讨论】:
-
如果
is.available()因为 C++ 程序还没有打印任何东西而返回 0 会发生什么?我看不出这与 C++ 或 C++ 程序中的线程有什么关系。 -
好吧,你说得对。该问题将由Java程序引起。而
is.available()不返回 0,它是打印 C++ 程序的第一个输出。 -
is.available()不打印任何内容。它“返回对可以从此输入流读取(或跳过)的字节数的估计值,而不会被下一次调用此输入流的方法阻塞。” -
您的问题是关于为什么 java 程序不等待所有 C++ 线程完成以及为什么您没有从 C++ 程序获得所有输出。我想让你看看你的java程序在做什么。它会检查是否有任何内容可供阅读,如果没有,它将跳转到
waitFor()。你的java程序应该做的是从输入流中读取直到输入流关闭。 -
根本不要使用
available()。它会告诉您是否有可用的立即。如果从现在开始 10 毫秒打印某些内容,您的程序将被绊倒。完全避免这种方法。如果目前没有可用的输入,您想调用将 阻塞并等待 的东西。泰德的回答就是这样做的。
标签: java c++ linux multithreading