后来,我如何修改STD ::启动策略的STD :: async

How can I modify the std::launch policy afterwards for std::async?

本文关键字:STD 启动 策略 async 修改 何修改 后来      更新时间:2023-10-16

假设我想在我的C 代码中使用std::async进行并行性来运行计算重函数func。现在由于它是一个重型功能,我们可能首先使用std::launch::deferred策略,因为情况是我们可能不需要运行。

但是,如果我们再一次需要执行它们,将来,我们希望并行运行。然后,如何修改std::launch策略。

[好吧,有人可以说为什么您不突然突然您需要执行 std::async s。但是我在这里假设我不能那样做。]

或,除了使用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::launch::deferred定义std::async后,当人们调用.get()函数时,将保证运行 async (即并行(,而不是。http://en.cppreference.com/w/cpp/thread/launch说

它是在调用线程上执行的。

那么 async 的概念被宠坏了,对吗?

如果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();