0

我有来自 Web 服务的响应,如果数据项的数量很大,我想将其拆分为较小的请求并并行执行请求和随后对该请求的解析。本质上,当第一个请求解析数据时,后续请求应该获取它。

似乎有很多方法可以做到这一点,我想知道期货在这种情况下是否合适。我听到一些评论说期货不应该用于 IO,而论点则相反。

实际上,我正在尝试这样做:

void Service::GetData(const Defn &defn) {
    // Split up the request into chunks if the  list is large
    size_t chunk_size = CONFIG.GetInt("Limits","BatchSize");
    if(chunk_size == 0) {
        auto response = GetResponse(defn);
        Parse(defn, *response);
    } else {
        std::vector<std::future<std::unique_ptr<Response>>> futures;
        for(int batch_num = 0; batch_num < (std::ceil(cardinality / chunk_size)); batch_num++) {
            futures.emplace_back(std::async(std::launch::async, &Service::GetResponse, defn, chunk_size, batch_num * chunk_size));
        }
        for(auto&& future : futures ) {
            Parse(defn, *future.get());
        }
    }
}

std::unique_ptr<Response> Service::GetResponse(const Defn &defn, size_t top, size_t skip) {
    // Do request and return response
}

但是,我收到一个错误“错误 C2064:术语不计算为采用 3 个参数的函数”,我不知道为什么。期货是否不允许将它们放入诸如向量之类的容器中?

如果是这样,我应该以不同的方式处理这个问题,还是有不同的方法来获取期货列表?即我必须使用打包任务吗?

理想情况下,我认为,这应该与内核数量更接近,而不是随意地将响应分成块,然后尝试为每个块创建一个线程。

4

1 回答 1

1
futures.emplace_back(
    std::async(std::launch::async,
        &Service::GetResponse, pService, defn, chunk_size, batch_num * chunk_size)
//                             ^^^^^^^^
    );

由于 GetResponse 不是静态成员函数,因此您应该将对象作为参数。


我不知道你具体是做什么的,所以我不能给你具体的建议>o<

但是,如果你对异步任务感兴趣future,我会向你介绍boost.asio。它是一个异步 I/O 库(是的,AS同步I / O),可以轻松地与std::futureor协作boost::future。(看到这个我的问题

在你的代码中,我认为Parse()也可以进入future.

futures.emplace_back(
    std::async(std::launch::async,
        [&] { GetResponse(...); Parse(...); }
    )
);

如果Parse不需要在同一个线程中运行或顺序运行,我认为它更好 - 你可以并行运行几个Parse和几个GetResponse

于 2015-02-11T03:28:53.860 回答