如何获得未来价值?

时间:2017-05-19 03:36:37

标签: c++ multithreading boost

在使用packaged_task时,我收集了一个向量中的所有未来。之后,我用get()推回未来的值。但是,我得到了错误的答案。有人可以帮忙吗?非常感谢你。

#define BOOST_THREAD_PROVIDES_FUTURE

#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>

using namespace std;

vector<int> subFun(int n) {

    vector<int> a{ 2 * n, 3 * n };

    return a;
}

int main() {

    vector<boost::future<vector<int>>> g;
    vector<vector<int>> x(10, vector<int>(2));
    int i;

    for (i = 0; i < 10; i++) {
        boost::packaged_task<vector<int>> task{ boost::bind(&subFun, i) };
        g.push_back(task.get_future());
        boost::thread t{ std::move(task) };
    }

    for (auto& m : g) {
        x.push_back(m.get());
    }

    cout << x[3][0] << endl;//should be 6, now is 0

    return 0;
}

2 个答案:

答案 0 :(得分:0)

经过多次修补后,我发现这个程序没有中止陷阱(我很惊讶你没有得到):

#include <future>
#include <thread>
#include <functional>
#include <vector>
#include <iostream>

std::vector<int> subFun(int n) {

    std::vector<int> a { 2 * n, 3 * n };

    return a;
}

int main() {

    std::vector<std::future<std::vector<int>>> g;
    std::vector<std::vector<int>> x;

    int i;

    for (i = 0; i < 10; i++) {
        std::packaged_task<std::vector<int>(int)> task{ subFun };
        g.push_back(task.get_future());
        std::thread { std::move(task), i }.detach();
    }

    for (auto& m : g) {
        m.wait();
        x.push_back(m.get());
    }

    std::cout << x[3][0] << std::endl; // is now 6

    return 0;
}

根据需要转换为boostThis answer对于发现几个关键问题非常有帮助。

答案 1 :(得分:0)

最重要的问题是你将push_back引入x,但你已经在这里进行了初始化:

vector<vector<int>> x(10, vector<int>(2));

因此,您只需添加10个 更多 元素,而不是将结果放在索引0..9。我建议不要预先填写,例如@ patrick的答案,或者填写指定的插槽:

#define BOOST_THREAD_PROVIDES_FUTURE

#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>

using namespace std;

void subFun(int n, vector<int>& into) {
    into = { 2 * n, 3 * n };
}

int main() {
    vector<boost::future<void>> futures;
    vector<vector<int>> x(10, vector<int>(2));

    for (size_t i = 0; i < x.size(); i++) {
        boost::packaged_task<void> task{ boost::bind(&subFun, i, std::ref(x[i])) };
        futures.push_back(task.get_future());
        boost::thread(std::move(task)).detach();
    }

    for (auto& f : futures)
        f.wait();

    cout << x[3][0] << endl;
}

当然,你可能会更复杂:

#define BOOST_THREAD_PROVIDES_FUTURE

#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>

struct TaskResult {
    int index;
    std::vector<int> data; 
};

TaskResult subFun(int n) {
    return { n, { 2 * n, 3 * n } };
}

int main() {
    std::vector<boost::future<TaskResult>> futures;
    std::vector<std::vector<int>> x(10, std::vector<int>(2));

    for (size_t i = 0; i < x.size(); i++) {
        boost::packaged_task<TaskResult> task{ boost::bind(&subFun, i) };
        futures.push_back(task.get_future());
        boost::thread(std::move(task)).detach();
    }

    for (auto& f : futures) {
        auto r = f.get();
        x[r.index] = r.data;
    }

    std::cout << x[3][0] << std::endl;
}