分解任务的期货向量?
Vector of futures for breaking up tasks?
我收到一个 Web 服务的响应,如果数据项的数量很大,我想将其拆分成更小的请求,并并行执行请求和对该请求的后续解析。本质上,当第一个请求解析数据时,后续请求应该获取它。
似乎有很多方法可以做到这一点,我想知道 futures 在这种情况下是否合适。我听到一些评论说 futures 不应该用于 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
}
但是,我收到一个错误 "error C2064: term does not evaluate to a function taking 3 arguments",我不确定为什么。 future 是否不允许将它们放入 vector 等容器中?
如果是这样,我应该以不同的方式处理这个问题,还是有不同的方法来获取期货清单? IE。我必须使用打包任务吗?
理想情况下,我想,这应该更接近核心数量,而不是随意地将响应分成块,然后尝试为每个块创建一个线程。
futures.emplace_back(
std::async(std::launch::async,
&Service::GetResponse, pService, defn, chunk_size, batch_num * chunk_size)
// ^^^^^^^^
);
由于 GetResponse 不是静态成员函数,您应该将对象作为参数。
我不知道你确切地是做什么的,所以我不能给你具体的建议>o<
但是,如果您对 future
的异步任务感兴趣,我会向您介绍 boost.asio. It's an asynchronous I/O library (yes, ASynchronous I/O) which easily cooperate with std::future
or boost::future
. (See this my question)
在你的代码中,我认为 Parse()
也可以进入 future
。
futures.emplace_back(
std::async(std::launch::async,
[&] { GetResponse(...); Parse(...); }
)
);
如果 Parse
不需要 运行 在同一个线程中或 运行 连续,我认为这样更好 - 你可以 运行 几个 Parse
和几个 GetResponse
并行。
我收到一个 Web 服务的响应,如果数据项的数量很大,我想将其拆分成更小的请求,并并行执行请求和对该请求的后续解析。本质上,当第一个请求解析数据时,后续请求应该获取它。
似乎有很多方法可以做到这一点,我想知道 futures 在这种情况下是否合适。我听到一些评论说 futures 不应该用于 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
}
但是,我收到一个错误 "error C2064: term does not evaluate to a function taking 3 arguments",我不确定为什么。 future 是否不允许将它们放入 vector 等容器中?
如果是这样,我应该以不同的方式处理这个问题,还是有不同的方法来获取期货清单? IE。我必须使用打包任务吗?
理想情况下,我想,这应该更接近核心数量,而不是随意地将响应分成块,然后尝试为每个块创建一个线程。
futures.emplace_back(
std::async(std::launch::async,
&Service::GetResponse, pService, defn, chunk_size, batch_num * chunk_size)
// ^^^^^^^^
);
由于 GetResponse 不是静态成员函数,您应该将对象作为参数。
我不知道你确切地是做什么的,所以我不能给你具体的建议>o<
但是,如果您对 future
的异步任务感兴趣,我会向您介绍 boost.asio. It's an asynchronous I/O library (yes, ASynchronous I/O) which easily cooperate with std::future
or boost::future
. (See this my question)
在你的代码中,我认为 Parse()
也可以进入 future
。
futures.emplace_back(
std::async(std::launch::async,
[&] { GetResponse(...); Parse(...); }
)
);
如果 Parse
不需要 运行 在同一个线程中或 运行 连续,我认为这样更好 - 你可以 运行 几个 Parse
和几个 GetResponse
并行。