【问题标题】:How to get the future value?如何获得未来价值?
【发布时间】:2017-10-19 01:12:49
【问题描述】:

在使用 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;
}

【问题讨论】:

  • 你为什么不用std::promise?顺便说一句,这些现在都在标准库中。还有,标记 c++
  • 想通了!

标签: c++ multithreading boost


【解决方案1】:

经过多次修改,我发现这个程序可以在没有中止陷阱的情况下工作(我很惊讶你没有得到):

#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 在发现几个关键问题方面非常有帮助。

【讨论】:

  • 谢谢。我加了m.wait(),结果还是0而不是6。
  • 中止陷阱可能是由于(不相关的)竞争导致main 在线程消失之前结束。除非分离,否则未加入的线程会触发异常程序终止。
  • 非常感谢您的所有回答。我对未来有了更清晰的认识。
【解决方案2】:

最现实的问题是你 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-06
    • 2014-03-01
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多