When you call std::async, you pass it the address of a function to call (along with any parameters you want to pass to that function).
It then creates a thread to execute that function asynchronously. It returns a future, which the parent thread can use to get the result from the child. Typical usage is something like this:
#include <string>
#include <future>
#include <iostream>
#include <chrono>
std::chrono::seconds sec(1);
int process() {
std::cerr << "Doing something slow\n";
std::this_thread::sleep_for(sec);
std::cerr << "done\n";
return 1;
}
int main(int argc, char **argv) {
if (argc > 1) {
auto func = std::async(process);
std::cerr << "doing something else that takes a while\n";
std::this_thread::sleep_for(sec);
func.get();
}
}
Note that we only have to use .get on the returned future to synchronize the threads. The sleep_for is just to simulate each thread doing something that takes at least a little while--if they finished too quickly, they wouldn't get a chance to really execute in parallel, since the first to run could finish and exit before the second got a chance to start running at all.
If you want to create explicit threads (i.e., create instances of std::thread), that's when you end up using std::wait_for and such (or can end up using them, anyway). With futures (i.e., what you create with std::async) you just use .get to wait for the thread to finish and retrieve whatever the thread function returned.
std::condition_variable?