Прежде всего, вы можете рассмотреть возможность избежать всего явного управления потоками и вместо этого использовать std::async
для запуска ваших задач в произвольном количестве отдельных потоков.
Во-вторых, вместо ввода-вывода в самих потоках, вы хотите создать результаты и сделать вывод сам по себе. Это означает, что функция потока просто создает некоторые данные и оставляет их вызывающей стороне, чтобы фактически записать это:
std::string process(int value) {
std::ostringstream buffer;
buffer << "my" << std::setfill('0') << std::setw(2) << value;
return buffer.str();
}
Затем нам нужно запустить четыре копии этого асинхронно:
std::vector<std::future<std::string> > results;
for (int i=0; i<4; i++)
results.push_back(std::async(std::launch::async, process, i));
Затем мы получаем результаты и распечатываем их по порядку:
for (auto &r : results)
std::cout << r.get() << "\n";
Собрав их вместе, мы могли бы получить код, подобный этому:
#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";
}
}
Я должен добавить один незначительный момент: я основываю это на стандартных C ++ 11 future
s. Я считаю, что основная идея должна также работать с Boost future
s (на котором основан стандарт), но я не проверял это. Я ожидаю, что для работы с фьючерсами Boost потребуются некоторые незначительные изменения (например, в именах).