Is std :: async guaranteed to call functions that return void?

I wrote the following code to test std::async() functions returning void from GCC 4.8.2 on Ubuntu.

 #include <future> #include <iostream> void functionTBC() { std::cerr << "Print here\n"; } int main(void) { #ifdef USE_ASYNC auto i = std::async(std::launch::async, functionTBC); #else auto i = std::async(std::launch::deferred, functionTBC); #endif //i.get(); return 0; } 

If i.get(); uncommented, the message "Print here" always exists; However, if i.get(); commented out, "Print here" exists if and only if USE_ASYNC is defined (that is, std::launch::async always results in a message printed while std::launch::deferred never).

Is this guaranteed behavior? What is the correct way to ensure void asynchronous call returns?

+5
source share
1 answer

std::launch::deferred means "don't run it until there is .wait() or .get() ."

Like you never .get() or .wait() ed, it never started.

void has nothing to do with it.

For std::launch::async , the standard states that the returned future destructor ( ~future ) will be blocked until the task completes (i.e. it has an implicit .wait() ). This violates the MSVC specifically because they disagree with this design decision and they are fighting for a change in the standard: in practice, this means that you cannot generally rely on any behavior from std::launch::async returned by future , if you want for future code.

Without the implicit wait in ~future it would be undefined if it would actually call the function when main exits. It would happen or not. Perhaps you could call UB while still having active threads at the end of main .

You may wonder what deferred uses: you can use it to compute a queue for lazy evaluation.

+7
source

All Articles