[英]std::future: Async single producer + any number of consumers problem
[英]Is there any potential problem in the code snippet below if `std::future::get()` would not be called?
如果不调用std::future::get()
,下面的代码片段中是否存在任何潜在问题?
我做了几个测试。 似乎上述代码在不调用std::future::get()
的情况下运行良好,即使std::async
需要很长时间才能完成其工作。 真是出乎我的意料。
#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
}
根据有关std::future 析构函数的文档(强调我的):
这些操作不会阻塞共享状态准备就绪,除非满足以下所有条件时可能会阻塞:共享状态是通过调用 std::async 创建的,共享状态尚未准备好,并且这是对共享状态的最后引用。 (C++14 起)
但它似乎只能由C++14
和之后的C++11
保证。
在某些情况下,仍然需要显式调用std::future::get()
,例如:
#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;
}
以下是上述代码片段的输出:
main:140198225385280
0
producer:140198225381120
consumer:140198216988416
100000
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.