First of all, you can consider avoiding all the explicit flow control and instead use std::async to run your tasks in an arbitrary number of separate threads.
Secondly, instead of I / O in the threads themselves, you want to create results and perform the output yourself. This means that the stream function simply creates some data and leaves it to the caller to actually write this:
std::string process(int value) { std::ostringstream buffer; buffer << "my" << std::setfill('0') << std::setw(2) << value; return buffer.str(); }
Then we need to run four copies of this asynchronously:
std::vector<std::future<std::string> > results; for (int i=0; i<4; i++) results.push_back(std::async(std::launch::async, process, i));
Then we get the results and print them in order:
for (auto &r : results) std::cout << r.get() << "\n";
Putting them together, we could get code like this:
#include <string> #include <iostream> #include <thread> #include <future> #include <sstream> #include <vector> #include <iomanip> std::string process(int value) { std::ostringstream buffer; buffer << "my" << std::setfill('0') << std::setw(2) << value; return buffer.str(); } int main() { std::vector<std::future<std::string>> rets; for (int i=0; i<4; i++) rets.push_back(std::async(std::launch::async, process, i)); for (auto & t : rets) { t.wait(); std::cout << t.get() << "\n"; } }
I have to add one minor point: I base this on future C ++ 11 standards. I believe that the main idea should also work with future Boost (on which the standard was based), but I have not tested this. I expect that some minor changes (for example, to names) will be needed to work with Boost futures.
source share