4

Using C++11 std::async in this snippet:

int foo()
{
    ::sleep(2);
    return 123;
}

int main()
{
    future<int> r1(async(foo));
    int r2 = foo();
    cout << r1.get() + r2 << endl;
    return 0;
}

It produces the right result, but runs both foo's serially (whole app runs 4 seconds). Compiled as: g++ -std=gnu++11 -O2 foo.cc -lpthread (Ubuntu 12.10 64bit, gcc 4.7.2)

Cartesius00
  • 23,584
  • 43
  • 124
  • 195
  • Note that even though g++ supports the syntax of `async`, its implementation is fairly immature (compared to say, MSVC's). – Matthieu M. Nov 17 '12 at 16:26
  • Oh, I see... so the answer is, it's a mock implementation right now? – Cartesius00 Nov 17 '12 at 16:27
  • 7
    [std::async without a launch policy lets the runtime library choose whether to start a new thread or run the task in the thread that called get() or wait() on the future.](http://stackoverflow.com/a/12510731/179910) – Jerry Coffin Nov 17 '12 at 16:30
  • 1
    @Martin: I would not say mock, but it's pretty raw. For example, if you specify `async` as a policy the runtime can either launch a new thread or take it from a pool (which may delay its launch if said pool is empty). In gcc, it always launch a new thread, so by the time you get to a thousand threads... you are in trouble. – Matthieu M. Nov 17 '12 at 16:47

2 Answers2

10

You might need to add a launch policy of std::launch::async:

std::async(std::launch::async, foo);
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

std::future has been criticized e.g. in this CppCon presentation for being slow. You can avoid std::async and std:future entirely by using this header-only library. You can run any number of functions asynchronously and get the results as a tuple. Also exceptions can be caught normally.

Here is an example:

    #include <iostream>
    #include "Lazy.h"

    template <class T>
    T foo(T x) {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        return x + 10.5;
    }

    int main() {
        int input = 54;
        try {
            auto [i, d, c] = Lazy::runParallel(
                                [&](){ return foo(int(input)); },
                                [&](){ return foo(double(input)); },
                                [&](){ return foo(char(input)); } );
            std::cout << "foo(int) = " << i << ", foo(double) = " << d << ", foo(char) = " << c << '\n';
        }
        catch (...) {
            // Deal with the exception here
        }
    }

    /* Output:
       foo(int) = 64, foo(double) = 64.5, foo(char) = @
    */
Keijo
  • 176
  • 7