Предположим, я хочу использовать std::async
для параллелизма в моем коде C ++, чтобы запустить вычислительно тяжелую функцию func
, Теперь, поскольку это тяжелая функция, мы могли бы сначала использовать std::launch::deferred
политика для этого, поскольку ситуация такова, что нам, возможно, не нужно бежать в конце концов.
Но опять же, если когда-либо нам нужно выполнить их вдруг, внезапно в будущем мы хотим работать параллельно. Тогда как мы можем изменить std::launch
политика потом.
std::async
как вдруг, внезапно вам нужно выполнить. Но я предполагаю, что я не могу этого сделать.]
Или есть ли лучший и более чистый способ сделать это, кроме использования std::async
?
Любая помощь высоко ценится. Заранее спасибо.
#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;
}
Размышление немного больше приводит меня к этой проблеме:
После определения std::async
с std::launch::deferred
когда один вызывает .get()
функция, будет ли тогда гарантированный бежать асинхронной (то есть параллельно) Конечно, нет. http://en.cppreference.com/w/cpp/thread/launch говорит
он выполняется в вызывающем потоке.
Тогда само понятие асинхронной портится, верно?
Если std::async
использования std::launch::deferred
тогда он запускается, когда возвращается std::future
объекты get()
функция называется.
Это говорит о том, что вы могли бы заставить std::launch::async
как это:
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();
Других решений пока нет …