I am writing a program that uses 2 threads in C++, the first one that waits for commands and prints the outputs on std::cout asynchronously and the second one that gathers this output and parses it via a pipe.
firstThread = std::thread([] () {
    Lib::loop(); // waits for commands from cin `(getline(cin, ...))`, does its magic and prints the output
});
CONSOLE OUTPUT: 
> first result 
> second result 
> third result
...
To pass those informations to a second thread I close std::cout, open a pipe, and redirect it to the second one via a file descriptor
int read_out_fd;
int write_out_fd;
int vals[2];
pipe(vals);
read_out_fd = vals[0];
write_out_fd = vals[1];
close(STDOUT_FILENO);  
dup(write_out_fd)
using the read() method in the second thread I wait for those outputs to be written by firstThread, gather them as they come, and parse them to build an array of string.
readThread = std::thread([] () {
    #define MAX_LEN 10
    char buffer[MAX_LEN+1] = {0};
    string output;
    vector<string> messages;
    
    while(read(read_out_fd, buffer, MAX_LEN)) {
        output += buffer;
        
        if(strlen(buffer) < MAX_LEN)
            output += '\n';
        
        memset(buffer, 0, sizeof buffer);
        
        if (output.find('\n')) {
            stringstream stream(output);
            string message;
            vector<string> messages_buffer;
            while(getline(stream, message)){
                messages_buffer.push_back(message);
            }
            
            output = messages_buffer.back();
            messages_buffer.pop_back();
            messages.insert( messages.end(), messages_buffer.begin(), messages_buffer.end());
        }
    }
});
This actually works, it transforms the stream of outputs from the first thread into an array (vector) of strings as they come:
messages : { "first result", "second result", "third result" }
However, I can feel that this method is convoluted. I am new to c++ and I don't know if this is the proper way to tackle this problem. Is there a better/easier way to gather and parse this output?
Notes:
- I cannot modify anything inside 
Lib::loop, this is a third part library. - I cannot 
fork()either since this c++ code is embedded in an iOS project (or I didn't find how) - I tried all the methods on this post but none of them worked for me for various reasons (missing libraries such as boost which I don't want to use, c++11 requirements etc...)
 
Aucun commentaire:
Enregistrer un commentaire