【问题标题】:How can I modify the std::launch policy afterwards for std::async?之后如何为 std::async 修改 std::launch 策略?
【发布时间】:2017-04-23 17:34:57
【问题描述】:

假设我想在我的 c++ 代码中使用 std::async 进行并行处理,以运行计算量大的函数 func。现在因为它是一个繁重的函数,我们可能首先使用std::launch::deferred 策略,因为情况是我们可能根本不需要运行。

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

[嗯,可以说,你为什么不突然创建std::asyncs,因为突然你需要执行。但我在这里假设我不能这样做。]

或者,除了使用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()函数时,是否保证运行异步(即并行)当然,不是。 http://en.cppreference.com/w/cpp/thread/launch

它在调用线程上执行。

那么异步的概念就被破坏了,对吧?

【问题讨论】:

  • 为您的启动策略使用变量?
  • @Galik:我该如何使用它?
  • 等一下,您要在创建std::async 对象之后更改午餐政策吗?
  • 我不认为(目前)使用标准 STL。如果你创建一个带延迟的异步,它不会在你调用 get() 之前启动,所以你可以调用 get() “just”来开始计算。
  • @ffslq: async 是一个满足简单需求的简单工具。如果您的需求更复杂,那么您应该构建一个满足这些需求的工具,而不是依赖async

标签: c++ asynchronous parallel-processing c++14 launch


【解决方案1】:

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

【讨论】:

  • 不应该是[&amp;]{return v1.get();})[&amp;]{return v2.get();})吗?似乎它正在工作。谢谢。
  • 但我们现在仍在创建另外两个std::asyncs。不管怎样,看来这是唯一的办法了。
  • @ffslq 是的,我更新了示例以返回值。
猜你喜欢
  • 2012-04-01
  • 1970-01-01
  • 2012-07-13
  • 2020-11-19
  • 1970-01-01
  • 2012-04-21
  • 1970-01-01
  • 2015-08-28
  • 2022-07-06
相关资源
最近更新 更多