I'm working on a program where I'd like to use async in a loop. In the example code I've included there's only 10 elements, so I could easily create an explicit variable for each element. However, in my main program, the number of elements in the vector can vary. Ideally, I'd like to create a vector of async threads - one for every element in the array - which are pushed back on the async vector as I loop through.Then I want to wait for them all to complete, and then use "get()" to return all of their outputs.
The code below will call async by assigning an explicit variable for each thread, but does anyone know how to dynamically call async in a vector without having to explicitly assign a variable to it? Ideally, I'd like for this program to call "std::cout" once for each time it looped through, instead of just once.
#include <iostream>
#include <vector>
#include <string>
#include <future>
std::string hi (std::string input)
{
return "hello, this is " + input;
}
int main()
{
std::vector<std::string> test_vector( 10, "a test" );
std::future<std::string> a;
std::future<std::string> b;
for ( int i = 0; i < test_vector.size ( ); i++ )
{
a = std::async(std::launch::async, hi, test_vector[i]);
}
std::cout << a.get() << std::endl;
return 0;
}
If the async flag is set, then a callable function will be executed in a separate thread. If the deferred flag is set, a callable function will be stored together with its arguments, but the std::async function will not launch a new thread.
If the deferred flag is set (i.e. (policy & std::launch::deferred) ! = 0), then async converts f and args... the same way as by std::thread constructor, but does not spawn a new thread of execution.
With a std::async call the return value of the supplied function (as determined by std::result_of) sets the template type of the returned std::future: // function returns an int so std::async() returns a std::future<int> std::future<int> fut = std::async(std::launch::async, []{ return 1; });
You can solve this by creating a vector of futures to match your threads vector, something like this:
#include <iostream>
#include <vector>
#include <string>
#include <future>
std::string hi(const std::string& input)
{
return "hello, this is " + input;
}
int main()
{
std::vector<std::string> tests = {"one", "two", "three", "four"};
std::vector<std::future<std::string>> futures;
// add the futures to the futures vector as you launch
// your asynchronous functions
for(auto&& t: tests)
futures.emplace_back(std::async(std::launch::async, hi, std::cref(t)));
// collect your results
for(auto&& f: futures)
std::cout << f.get() << '\n';
}
Note the use of std::cref to pass by const reference. Use std::ref to pass non const references.
An answer including std::cout
:
std::vector<std::future<std::string>> a;
for (int i = 0; i < 10; ++i) {
a.emplace_back(std::async(hi));
}
for (auto& element : a) {
std::cout << element.get() << std::endl;
}
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