简体   繁体   English

如何为std :: async修改std :: launch策略?

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

Suppose I want to use std::async for parallelism in my c++ code to run a computationally heavy function func . 假设我想在我的c ++代码中使用std::async进行并行操作来运行计算量很大的函数func Now since it is a heavy function, we might at first use std::launch::deferred policy for it as the situation is that we may not need to run after all. 既然它是一个繁重的函数,我们可能首先使用std::launch::deferred策略,因为我们可能根本不需要运行它。

But again if ever we need to execute them suddenly in the future, we desire to run in parallel. 但是,如果我们将来需要突然执行它们,我们希望并行运行。 Then how can we modify the std::launch policy afterwards. 然后我们如何修改std::launch策略。

[Well, one can say that why don't you then suddenly create the std::async s as suddenly you need to execute. [嗯,有人可以说你为什么不突然创建std::async s 突然你需要执行。 But I am assuming here that I cannot do that.] 但我在这里假设我做不到。]

Or, is there any better and cleaner way to do this other than using std::async ? 或者,除了使用std::async之外,还有更好更清洁的方法吗?

Any help is highly 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 UPDATE

Thinking a little bit more leads me with this issue: 更多地思考这个问题导致我:

After defining the std::async with std::launch::deferred , when one calls the .get() function, will it then be guaranteed to run async (ie in parallel) Surely, not. 在使用std::launch::deferred定义std::async之后,当一个人调用.get()函数时,它是否会保证运行异步 (即并行)当然,不是。 http://en.cppreference.com/w/cpp/thread/launch says http://en.cppreference.com/w/cpp/thread/launch

it is executed on the calling thread. 它在调用线程上执行。

Then the very notion of async gets spoilt, right? 那么异步的概念会被破坏,对吧?

If the std::async uses std::launch::deferred then it is run when the returned std::future object's get() function is called. 如果std::async使用std::launch::deferred则在调用返回的std::future对象的get()函数时运行它。

This suggests you could force std::launch::async like this: 这表明你可以像这样强制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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM