Experimenting with the future

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

Leave a comment