std::async not executing when specifying launch::async

asynchronous, c++, c++11, multithreading

Solution

The first thing you have to know is that MSVC `std::async` does not conform to the C++11 standard.

Under the C++11 standard, `std::async`'s `std::future` return value blocks until the `std::async` completes.

MSVC's implementation does not. This makes their `std::async` seemingly more friendly to use, but in practice it is quite tricky.

However, as `std::async`'s behavior is described in terms of `std::thread`, we can look at what happens when you kick off a `std::thread` and fail to clean it up. The resulting `std::thread` is effectively detached. Once you exit `main`, the C++ standard does not specify what happens to such `std::thread`s, leaving it up to your particular implementation.

Based off some quick research, when a MSVC windows program goes off the end of main, the threads are terminated.

In short, your program needs to resynchronize with the threads you launched in some way or another, so that they can complete their tasks, and prevent the main program from exiting `main`. An easy way to do that is to store the returned `std::future` from your `async` task, and `wait` on it before `main` exits.

If you had a conforming C++11 compiler, your attempted `async` would fail to be asynchronous, as it would block immediately upon the destruction of the anonymous `std::future` it returned.

Finally, note that launched `thread`s and the like may not be scheduled to run immediately after creation. How and when they run is not predictable.

The C++11 concurrency primitives are merely primitives. Many of them have quirky behavior, like the fact that a `std::thread` calls `terminate` if it is destroyed without being `detach`ed or `join`ed, and `async`'s tendency to block if you don't store the `future`. They can be used for simple tasks, or for writing higher level libraries, but they are not user friendly.

Problem

Maybe I'm missing the correct usage of the new `std::async` in C++11, however this statement (over at cppreference.com): If the async flag is set (i.e. policy & std::launch::async != 0), then async executes the function f on a separate thread of execution as if spawned by std::thread(f, args...), except that if the function f returns a value or throws an exception, it is stored in the shared state accessible through the std::future that async returns to the caller. Makes me think that my thread should start immediately with this statement: ``` std::async(std::launch::async, MyFunctionObject()); ``` Without having to wait for calling the `std::future::get()`. This seems to not be the case (compiling with MSVC 13). If this is not triggered by this statement itself, how should this get triggered if I don't care about the return value of the `std::future` object? Example: ``` #include <thread> #include <iostream> #include <array> #include <future> static std::mutex write_mutex; class Cpp11Threads { public: // Function operator for Function-Object void operator()() { const int num_threads = 50; // Static std array std::array<std::thread*, num_threads> worker_threads; // Range based for (std::thread*& thread : worker_threads) { // Lambda expression thread = new std::thread( [] { static int i = 0; write_mutex.lock(); std::cout << "Hello, I am happy Std thread #" << i++ << std::endl; write_mutex.unlock(); }); } for (std::thread*& thread : worker_threads) { thread->join(); delete thread; // nullptr instead of NULL thread = nullptr; } } }; int main() { std::async(std::launch::async, Cpp11Threads()); return 0; } ```

Original source

Related problems