std::async has an overload which takes a std::launch policy as the first argument. When should I use this overload? what are the different policies available? (I think sync and async are the two options). When should I use the sync policy? How is that different from directly running it?
Summary from the very helpful article that Jagannath linked, and comments on the possible uses.
There are 3 launch policies:
any
: the library chooses whether to spawn a thread a or notasync
: you explicitly ask for a thread to be spawneddeferred
: you explicitly ask for a thread not to be spawnedTherefore, the deferred
policy is a way to get deterministic lazy evaluation (also known as call by need). For example, suppose that you have:
void MyClass::lazy(std::future<int> const& f) {
if (this->notReady()) { return; }
if (this->stillNotReady()) { return; }
if (this->value() == 42) { return; }
this->go(f.get());
}
Now, if computing the value of this integer is long (for example, it may invoke a network roundtrip), then it's kinda wasteful to compute it in all the cases that do not really require it... and now we've got the tool to do so!
void func(MyClass& mc) {
std::future<int> f = std::async(std::launch::deferred, []() {
return stoi(memcached.get("KEY"));
});
mc.lazy(f);
}
Note that this is subtly different from using a std::function<int()>
(and a closure), because the computation is done once and for all, guaranteeing that subsequent calls to get always return the same result.
The difference with the other policies can also be expressed in term of whether the operation is performed when you do not need the value.
any
: might be performed on another thread (proactively) or not performed at allasync
: will be performed on another threaddeferred
: will not be performedTherefore, deferred
gives you better control, which is important if the call has a side effect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With