I'm trying to speed up a file parser by using multi threading. I've created a function that reads and parses a json-file and returns a vector.
Now, to speed things up, i tried to use async, so i created a future vector to store the results. When each thread is finished (ran the parsing function), i would like to append the results to a vector that stores all the results.
#include <vector>
#include <iostream>
#include <future>
std::vector<int> parsefilefunction(std::string filepath)
{
std::vector<int> vec{1, 2, 3};
return vec;
}
std::vector<std::string> s = {
"file1.json",
"file2.json",
"file3.json",
"file4.json",
"file5.json"};
int main()
{
std::vector<int> results2;
for (size_t i = 0; i < s.size(); i )
{
std::future<std::vector<int>> results = std::async(std::launch::async, parsefilefunction, s[i]);
results2.push_back(results); //this is not working, i already tried with move()
}
}
It would be super cool if you can help me! Thank you!
Edit: Indeed, "is not woking" is a terrible question desciption!
Compiled with:
c stackoverflow.cpp -std=c 14 -pthread
Error message:
error: no matching member function for call to 'push_back'
results2.push_back(results);
~~~~~~~~~^~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c /v1/vector:713:36: note: candidate function not viable: no known conversion from 'std::future<std::vector<int>>' to 'const std::__vector_base<int, std::allocator<int>>::value_type' (aka 'const int') for 1st argument
_LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c /v1/vector:716:36: note: candidate function not viable: no known conversion from 'std::future<std::vector<int>>' to 'std::vector<int>::value_type' (aka 'int') for 1st argument
_LIBCPP_INLINE_VISIBILITY void push_back(value_type&& __x);
CodePudding user response:
You want to store int
s in your vector
, but have a std::future
, that is not going to work. You have to get the vector
out of the future
and then copy its elements.
But with that approach you would have no async operation, since you always wait for the single operation to finish before you start the next one.
Here is an updated version which compiles: https://gcc.godbolt.org/z/jE171j7GG
#include <algorithm>
#include <future>
#include <iterator>
#include <vector>
std::vector<int> parsefilefunction(std::string filepath)
{
std::vector<int> vec{1, 2, 3};
return vec;
}
std::vector<std::string> s = {
"file1.json",
"file2.json",
"file3.json",
"file4.json",
"file5.json"};
int main()
{
std::vector<std::future<std::vector<int>>> futures;
std::vector<int> results2;
for (const auto& file : s)
{
//Start async operations
futures.emplace_back(std::async(std::launch::async, parsefilefunction, file));
}
for (auto& future : futures)
{
//Merge results of the async operations
auto result = future.get();
std::copy(result.begin(), result.end(), std::back_inserter(results2));
}
}