What is the difference between async([](){}) and thread([](){}).detach()?
I know a good answer was given to your question but if we were to change your question a little something interesting would occur.
Imagine you kept the future returned by the async
and didn't detach the thread but instead made a variable for it like this,
Asynchronous code
auto fut=std::async([]() { ... });
std::thread th([]() { ... });
Now you have the setup to what makes these 2 constructs different.
th.join()//you're here until the thread function returns
fut.wait_for(std::chrono::seconds(1)); //wait for 1 sec then continue.
A thread
is an all or nothing thing when joining it where as an async
can be checked and you can go do other stuff.
wait_for
actually returns a status so you can do things like this.
int numOfDots = 0;
//While not ready after waiting 1 sec do some stuff and then check again
while(fut.wait_for(std::chrono::seconds(1)) != std::future_status::ready)
{
(numOfDots++)%=20;
//Print status to the user you're still working on it.
std::cout << "Working on it" <<std::string(numOfDots,'.')<<"\r"<<std::flush();
}
std::cout << "Thanks for waiting!\nHere's your answer: " << fut.get() <<std::endl();
std::async ([]() { ... }); // (1)
std::thread ([]() { ... }).detach (); // (2)
Most often when std::async
is being discussed the first thing noted is that it's broken, the name implies something which doesn't hold when the returned value isn't honored (assigned to a variable to be destructed at the end of the current scope).
In this case the brokenness of std::async
is exactly what is going to result in a huge difference between (1)
and (2)
; one will block, the other won't.
Why does std::async
block in this context?
The return-value of std::async
is a std::future
which has a blocking destructor that must execute before the code continues.
In an example as the below g
won't execute until f
has finished, simply because the unused return value of (3)
can't be destroyed until all work is done in the relevant statement.
std::async (f); // (3)
std::async (g); // (4)
What is the purpose of std::thread (...).detach ()
?
When detaching from a std::thread
we are simply saying; "I don't care about this thread handle anymore, please just execute the damn thing."
To continue with an example similar to the previous one (about std::async
) the difference is notably clear; both f
and g
will execute simultaneously.
std::thread (f).detach ();
std::thread (g).detach ();