使用C ++ 11的可变数量的异步线程

时间:2014-11-17 03:08:19

标签: c++ multithreading c++11 concurrency

我正在开发一个我想在循环中使用异步的程序。在示例代码中,我只包含了10个元素,因此我可以轻松地为每个元素创建一个显式变量。但是,在我的主程序中,向量中的元素数量可能会有所不同。理想情况下,我想创建一个异步线程的向量 - 一个用于数组中的每个元素 - 当我循环时,它们被推回到异步向量上。然后我想等待它们全部完成,然后使用“ get()“返回所有输出。

下面的代码将通过为每个线程分配一个显式变量来调用async,但有没有人知道如何在向量中动态调用async而不必为其明确赋值变量?理想情况下,我希望这个程序在每次循环时调用“std :: cout”一次,而不只是一次。

#include <iostream>
#include <vector>
#include <string>
#include <future>

std::string hi (std::string input)
{
    return "hello, this is " + input;
}

int main()
{
    std::vector<std::string> test_vector( 10, "a test" );
    std::future<std::string> a;
    std::future<std::string> b;

    for ( int i = 0; i < test_vector.size ( ); i++ )
    {
        a = std::async(std::launch::async, hi, test_vector[i]);
    }

    std::cout << a.get() << std::endl;

    return 0;
 }

3 个答案:

答案 0 :(得分:13)

你可以通过创建一个与你的线程向量匹配的期货向量来解决这个问题,如下所示:

#include <iostream>
#include <vector>
#include <string>
#include <future>

std::string hi(const std::string& input)
{
    return "hello, this is " + input;
}

int main()
{
    std::vector<std::string> tests = {"one", "two", "three", "four"};
    std::vector<std::future<std::string>> futures;

    // add the futures to the futures vector as you launch
    // your asynchronous functions
    for(auto&& t: tests)
        futures.emplace_back(std::async(std::launch::async, hi, std::cref(t)));

    // collect your results
    for(auto&& f: futures)
        std::cout << f.get() << '\n';
}

请注意使用std::cref传递 const引用。使用std::ref传递非常量引用

答案 1 :(得分:7)

答案包括std::cout

std::vector<std::future<std::string>> a;
for (int i = 0; i < 10; ++i) {
  a.emplace_back(std::async(hi));
}
for (auto& element : a) {
  std::cout << element.get() << std::endl;
}

答案 2 :(得分:3)

如果我理解正确,可能是这样的:

std::vector<std::future<std::string>> vessel;
for ( int i = 0; i < test_vector.size ( ); i++ )
{
    std::future<std::string> aux;
    aux = std::async(std::launch::async, hi);
    vessel.push_back(aux);
}

抱歉,我不能发表评论,但这样,根据逻辑,如果有效,那么你应该能够动态操纵向量vessel


<强>更新

更好的是:

vessel.push_back(new std::future<std::string>);
vessel[vessel.size()-1] = std::async(std::launch::async, hi);

这样您就不需要显式声明变量了。但是一旦完成,你将不得不delete

for(int i=0; i<(int) vessel.size(); i++)
{
    delete vessel[i];
}