Wait for a multithreading program written in C++ in java

Viewed 67

I written a program in C++ where multithreading is used. Call this program using a bash script or something like that is no problem, everything is working fine. Now I want to call this program in Java. This is the Java code sample I tried:

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();

So if I run this code, following will happen: It seems like the waitFor() instruction will not realy wait for "all" threads, maybe it will wait only for one. However, the java program executed with a error because it can't find files which are generated by the C++ program. So the waitFor() don't wait until my c++ program is finished and has generated the files.

The output is really weird too. I only get one output from std::cout. Here's an example:

std::cout << out_folder_path << "\n" << vcd_filename << "\n";
std::cout << std::flush;

This will print only the out_folder_path output. A problem is: In the section of the std::cout I don't even use multi-threading. All other std::cout in the program are don't printed too.

So my questions: How can I wait for really ALL threads? And how can I get the real output of my program?

1 Answers

Your program doesn't get all output from the C++ program because it doesn't read until the input streams are depleted. It jumps to waitFor if the C++ program has not produced any output when your program reaches is.available().

Here's an alternative approach doing reading until the input streams are closed. It uses an InputStreamReader and a BufferedReader and calls the BufferedReader's readline() until the input stream closes.

Disclaimer. I haven't written any java programs before so I'm not sure I've gotten everything correct. The general idea should work though.

var v2j = new ProcessBuilder("./src/main/cpp/vcd_converter", "-vcd", 
                             vcdfilePath, "-out", logfilePath).start();

InputStream is = v2j.getInputStream();
try(var reader = new BufferedReader(new InputStreamReader(is))) {
    String line;

    while ((line = reader.readLine()) != null) {
        System.out.println("Input: " + line);
    }
}

InputStream es = v2j.getErrorStream();
try(var reader = new BufferedReader(new InputStreamReader(es))) {
    String line;

    while ((line = reader.readLine()) != null) {
        System.out.println("Error: " + line);
    }
}

v2j.waitFor();
Related