I want to call a method with async multiple times. A simplified example is shown below:
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;
}
It seems that, fut.get() blocks other future calls. How can I implement this problem in C++? I need to call a function in a separate thread. This function "returns" a value.
In order to run multiple async/await calls in parallel, all we need to do is add the calls to an array, and then pass that array as an argument to Promise. all() . Promise. all() will wait for all the provided async calls to be resolved before it carries on(see Conclusion for caveat).
async and await Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
Use of async and await enables the use of ordinary try / catch blocks around asynchronous code. Note: The await keyword is only valid inside async functions within regular JavaScript code. If you use it outside of an async function's body, you will get a SyntaxError .
The async keyword turns a method into an async method, which allows you to use the await keyword in its body. When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete. await can only be used inside an async method.
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()
is blocking. So don't block until you have queue'd up all tasks.
An alternative plan is to write/find a thread pool, and have each task update a possibly atomic (or mutex guarded) counter.
Have a finished-task counter guarded (again, possibly atomic).
Have a promise (of the total) which you fulfill when the last task is finished (fulfilled by the last task).
Return the future from that promise. Now you have a future representing the entire pool of threads calculating their value and adding it up, with lots of concurrency.
Some frameworks, like microsoft's ppl, have a system where it does something like this for you; you have tasks that return values, and a function object that combines the values, and get the result of the combination out of it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With