我想多次调用异步方法。简化示例如下所示:
size_t counter(std::string &s)
{
return s.size();
}
void stringCountAccumulator()
{
std::vector<std::string> foos = {"this", "is", "spartaa"};
size_t total = 0;
for (std::string &s : foos)
{
std::future<size_t> fut = std::async(
std::launch::async,
counter, s);
total += fut.get();
}
std::cout << "Total: " << total;
}
看来,fut.get()会阻止其他未来的通话。如何在C ++中实现此问题?我需要在一个单独的线程中调用一个函数。这个功能&#34;返回&#34;价值。
答案 0 :(得分:3)
void stringCountAccumulator()
{
std::vector<std::string> foos = {"this", "is", "spartaa"};
std::vector<std::future<size_t>> calcs;
for (auto&& s : foos) {
calcs.push_back( std::async(
std::launch::async,
counter, s)
);
}
std::size_t total = 0;
for (auto&& fut:calcs)
total += fut.get();
std::cout << "Total: " << total << "\n";
}
.get()
正在阻止。所以不要阻止,直到排队完成所有任务。
另一种计划是编写/查找线程池,并让每个任务更新一个可能是原子(或互斥锁的)计数器。
保护完成的任务计数器(再次,可能是原子)。
在最后一个任务完成时(由最后一个任务完成),你有一个承诺(总数)。
从这个承诺中回归未来。现在,你有一个未来代表整个线程池计算它们的值并将其加起来,具有很多并发性。
有些框架,比如微软的ppl,有一个系统可以为你做这样的事情;你有返回值的任务,以及组合这些值的函数对象,并从中获取组合的结果。
答案 1 :(得分:1)
看看这个:C++ threads for background loading。这解释了如何获得任何已完成任务的结果。
答案 2 :(得分:1)
您还需要声明StringCountAccumulator()将异步执行。仅在未来准备就绪时调用future :: get()。这是一个代码段:
std::future<void> stringCountAccumulator()
{
std::vector<std::string> foos = {"this", "is", "spartaa"};
size_t total = 0;
for (std::string &s : foos)
{
std::future<size_t> fut = std::async(
std::launch::async, counter, s);
while (!fut.is_ready() ) ;
total += fut.get();
}
std::cout << "Total: " << total;
}