Reputation: 3484
Is there any potential problem in the code snippet below if std::future::get()
would not be called?
I did several tests. It seems that the said code works well without invoking std::future::get()
even if it takes std::async
a long time to finish its work . It's really out of my expectation.
#include<future>
#include<iostream>
#include<array>
#include<algorithm>
#include<thread>
#include<vector>
std::array<int, 100000> arr;
int sum=0;
struct Wrapper
{
void consume()
{
std::cout << "consumer:" << std::this_thread::get_id() << std::endl;
std::for_each(arr.begin(), arr.end(), [](int val) {sum+=val; });
}
void produce()
{
std::cout << "producer:" <<std::this_thread::get_id() << std::endl;
int a=0;
while(true)
{
if(a++>1e9)
{
break;
}
}
}
};
int main()
{
std::fill(arr.begin(), arr.end(), 1);
std::cout << "main:" <<std::this_thread::get_id() << std::endl;
Wrapper wrap;
std::vector<std::future<void>> vec;
vec.push_back(std::async(std::launch::async, &Wrapper::produce, &wrap));
vec.push_back(std::async(std::launch::async, &Wrapper::consume, &wrap));
#ifdef WAIT //Is there any potencial problem if the block below does not run?
for(auto& future:vec)
{
future.get();
}
#endif
}
Upvotes: 0
Views: 58
Reputation: 3484
As per the document about std::future destructor (emphasis mine):
these actions will not block for the shared state to become ready, except that it may block if all of the following are true: the shared state was created by a call to std::async, the shared state is not yet ready, and this was the last reference to the shared state. (since C++14)
But it seems only guaranteed by C++14
and afterwards other than C++11
.
And for some cases, std::future::get()
still needs to be explicitly called, for example:
#include<future>
#include<iostream>
#include<array>
#include<algorithm>
#include<thread>
#include<vector>
std::array<int, 100000> arr;
int sum=0;
struct Wrapper
{
void consume()
{
std::cout << "consumer:" << std::this_thread::get_id() << std::endl;
std::for_each(arr.begin(), arr.end(), [](int val) {sum+=val; });
}
void produce()
{
std::cout << "producer:" <<std::this_thread::get_id() << std::endl;
int a=0;
while(true)
{
if(a++>1e9)
{
break;
}
}
}
};
int main()
{
std::fill(arr.begin(), arr.end(), 1);
std::cout << "main:" <<std::this_thread::get_id() << std::endl;
Wrapper wrap;
std::vector<std::future<void>> vec;
vec.push_back(std::async(std::launch::async, &Wrapper::produce, &wrap));
vec.push_back(std::async(std::launch::async, &Wrapper::consume, &wrap));
std::cout << sum << std::endl;
#if 1
for(auto& future:vec)
{
future.get();
}
#endif
std::cout << sum << std::endl;
}
Here is the output of the said code snippet above:
main:140198225385280
0
producer:140198225381120
consumer:140198216988416
100000
Upvotes: 0