How can I change the std :: launch policy for std :: async?
Suppose I want to use std::async
parallelism in my C ++ code to run a heavy computational function func
. Now, since this is a heavy function, we can first use a policy for it std::launch::deferred
, since the situation is such that we may not need to run after all.
But if we ever need to fulfill them in the future, we will strive in parallel. Then how can we change the policy std::launch
.
[Well, you might say, why don't you create std::async
, when suddenly you need to execute. But I guess I can't.]
Or, is there a better and cleaner way to do this other than using it std::async
?
Any help is greatly appreciated. Thanks in advance.
#include <future>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <iostream>
std::vector<double> func(size_t n) // a computationally heavy function
{
std::vector<double> vec(n);
std::generate_n(vec.begin(), n, std::rand);
return vec;
}
int main()
{
// create asyncs, now deferred for lazy execution
auto v1 = std::async(std::launch::deferred, func, 200); // deferred for lazy execution
auto v2 = std::async(std::launch::deferred, func, 250); // deferred for lazy execution
// only after sometime we decide to execute both of them
// but we also now want them to execute in parallel
// so how can we now change the launch policy?
// to get the values as quickly as can be
auto n1 = v1.get().size();
auto n2 = v2.get().size();
std::cout<<"Got "<<n1<<" and "<<n2<<" random numbers in parallel!"<<std::endl;
return 0;
}
UPDATE
Thinking a little more leads me to this problem:
Once defined std::async
with std::launch::deferred
, when you call the function .get()
, then async is guaranteed to be executed (i.e. in parallel). Of course not. http://en.cppreference.com/w/cpp/thread/launch says
executed on the calling thread.
Then the very notion of async will screw up, right?
If std::async
used std::launch::deferred
, then it starts when you call the returned function std::future
object get()
.
This suggests that you can force it std::launch::async
like this:
int s1 = 0;
int s2 = 0;
auto v1 = std::async(std::launch::deferred, []{ return 1; });
auto v2 = std::async(std::launch::deferred, []{ return 2; });
// some fancy coding ...
if(need_to_upgrade_launch_policy())
{
auto v1a = std::async(std::launch::async, [&]{ return v1.get(); });
auto v2a = std::async(std::launch::async, [&]{ return v2.get(); });
s1 = v1a.get();
s2 = v2a.get();
}
// more clever coding ...
if(v1.valid()) // was never upgraded
s1 = v1.get();
if(v2.valid()) // was never upgraded
s2 = v2.get();
source to share