async, future and time: chrono
A function started in a std::thread cannot return a result: the thread discards the returned value. To get a result, you have to set up a shared variable and call join(). The std::async function from the <future> header makes this simpler. It starts a function and returns a std::future, an object from which you collect the result later:
#include <future>
#include <iostream>
int sum_to(int n) {
int sum = 0;
for (int i = 1; i <= n; ++i) {
sum += i;
}
return sum;
}
int main() {
std::future<int> result = std::async(std::launch::async, sum_to, 100);
std::cout << result.get() << '\n'; // 5050
}std::async passes the argument 100 to sum_to. The angle brackets of std::future<int> hold the result type. The call result.get() waits until the function finishes and returns its result. You can call get() on one std::future only once, while wait() only waits, without taking the result.
Launch policy
The first argument of std::async is the launch policy. With std::launch::async, the function runs in a new thread. With std::launch::deferred, it does not start right away: the first call to get() or wait() runs it in the calling thread. If neither is called, the function never runs at all.
You can leave the policy out: std::async(sum_to, 100). Then the standard library implementation chooses between async and deferred. If the task must run in parallel, pass std::launch::async explicitly.
Durations: chrono
A thread often needs to wait: std::this_thread::sleep_for pauses it for a given duration. Durations are expressed with the types std::chrono::seconds, std::chrono::minutes and std::chrono::milliseconds from the <chrono> header. The .count() method returns the number of units. The literals 2min, 30s and 500ms are available after the line using namespace std::chrono_literals;.
#include <chrono>
#include <iostream>
using namespace std::chrono_literals;
int main() {
std::chrono::seconds total = 2min + 30s;
std::chrono::milliseconds ms = total;
std::cout << total.count() << ' ' << ms.count() << '\n'; // 150 150000
}The sum 2min + 30s gets the type of the finer of the two units, that is, seconds. A duration converts to finer units by itself, since no precision is lost. The opposite conversion can lose a fraction, so it is written explicitly, with std::chrono::duration_cast. It rounds toward zero: std::chrono::duration_cast<std::chrono::seconds>(1500ms) equals 1s.
Common mistake
Milliseconds are assigned to seconds:
std::chrono::milliseconds ms{1500};
std::chrono::seconds s = ms; // ✗error: no viable conversion from 'duration<[...], ratio<[...], 1000>>' to 'duration<[...], ratio<[...], 1>>'This is a compiler error. The compiler checks the types, not the value: converting milliseconds to seconds can lose a fraction, even if ms held exactly 2000. If the loss is acceptable, convert with duration_cast.