I recently answered a question on Stack overflow about threads, and since I haven't used things like std::future and std::async before, I thought it would be a good time to write an experimental program with it.
After writing the answer on SO, I decided to make a more asynchronous by printing the result returned by the thread when I received it, so I wrote the program below for that:
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
#include <vector>
#include <random>
#include <unordered_map>
#include <unistd.h> // for `usleep`
std::chrono::milliseconds do_some_work()
{
auto start = std::chrono::system_clock::now();
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1000, 5000);
usleep(dis(gen) * 1000);
auto end = std::chrono::system_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
}
int main()
{
constexpr int N = 5;
std::vector<std::future<std::chrono::milliseconds>> results(N);
std::unordered_map<int, bool> ready;
// Start the threads
for (int i = 0; i < N; i++)
{
ready[i] = false;
results[i] = std::async(std::launch::async,
[](){ return do_some_work(); });
}
// Wait for all threads to be done and if done print the results
for (int i = 0; i < N; i++)
{
if (!ready[i] && results[i].wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
ready[i] = true;
std::cout << "Result from " << i << ": "
<< results[i].get().count() << " milliseconds\n";
}
}
}
Can be compiled with a recent version of GCC (at least 4.7 needed). Unfortunately there is a bug in the GCC standard C++ library which causes the program to segfault.
Command to compile the program:
$ g++ -pthread -std=c++11 future_test.cpp -o future_test
Edit 2012-11-11
After building this at home (Ubuntu 12.10 with GCC 4.7.2) I can run it, but it didn't produce any output. The bug is in the loop waiting for the threads to done, it just loops through once. Proper loop is:
// Wait for all threads to be done and if done print the results
bool all_ready;
do
{
all_ready = true;
for (int i = 0; i < N; i++)
{
if (!ready[i])
{
all_ready = false;
if (results[i].wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
ready[i] = true;
std::cout << "Result from " << i << ": "
<< results[i].get().count() << " milliseconds\n";
}
}
}
} while (!all_ready);