I've wrote the following code to test std::async()
on functions returning void
with 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();
is uncommented, the message "Print here"
always exists; however, if i.get();
is commented out, "Print here"
exists if and only if USE_ASYNC
is defined (that is, std::launch::async
always leads to message printed out while std::launch::deferred
never).
Is this guaranteed behavior? What's the correct way to ensure the asynchronous call returning void
to be executed?
std::launch::deferred
means "do not run this until I .wait()
or .get()
".
As you never .get()
or .wait()
ed, it never ran.
void
has nothing to do with this.
For std::launch::async
, the standard states that the returned future's destructor (~future
) will block until the task is complete (ie, has an implicit .wait()
). This is violated by MSVC on purpose, because they disagreed with that design decision, and they are fighting to change the standard: in practice, this means that you cannot rely on any behavior at all from std::launch::async
returned future
if you want to future-proof your code.
Without implicit wait
in ~future
, it would be indeterminate if it actually invoked the function when main
exited. It would either have happened, or not. Possibly you could invoke UB by having still-active threads at the end of main
.
You may wonder what use deferred
has: you can use it to queue up a computation for lazy evaluation.