无阻塞地开始剩余期货

时间:2014-04-08 11:15:19

标签: c++ multithreading c++11 future

我在一个集合上有一个循环,我必须执行昂贵的计算。我希望使用未来的类并行执行此操作。据我所知,async启动线程或推迟它并仅在我调用get()或wait()时启动它。因此,当我没有启动线程并尝试获取结果时,我阻止主线程获得顺序处理。有没有办法启动剩余的延迟进程,所以一切都是并行计算的,并且在调用get()时不会阻塞。

// do the calculations
std::vector<std::future<class>> futureList;
for (auto elem : container)
{
  futureList.push_back(std::async(fct, elem));
}

// start remaining processes

// use the results
for (auto elem : futureList)
{
  processResult(elem.get())
} 

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您可以使用:

std::async(std::launch::async, fct, elem)

样品:

#include <iostream>
#include <future>
#include <chrono>
#include <vector>
#include <stdexcept>

bool work() {
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    if( ! (std::rand() % 2)) throw std::runtime_error("Exception");
    return true;
}

int main() {
    const unsigned Elements = 10;

    typedef std::vector<std::future<bool>> future_container;
    future_container futures;

    for(unsigned i = 0; i < Elements; ++i)
    {
        futures.push_back(std::async(std::launch::async, work));
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }

    while( ! futures.empty()) {
        future_container::iterator f = futures.begin();
        while(f != futures.end())
        {
            if(f->wait_for(std::chrono::milliseconds(100)) == std::future_status::timeout) ++f;
            else {
                // Note:: Exception resulting due to the invokation of 
                //        the thread are thrown here.
                //        (See 30.6.6 Class template future)
                try {
                    std::cout << f->get() << '\n';
                }
                catch(const std::exception& e) {
                    std::cout << e.what() << '\n';
                }
                f = futures.erase(f);
            }
        }
    }
    return 0;
}

答案 1 :(得分:0)

您可以执行以下操作:(http://coliru.stacked-crooked.com/a/005c7d2345ad791c

创建此功能:

void processResult_async(std::future<myClass>& f) { processResult(f.get()); }

然后

// use the results
std::vector<std::future<void>> results;
for (auto& elem : futureList)
{
    results.push_back(std::async(std::launch::async, processResult_async, std::ref(elem)));
}