[英]C++ std::async() terminate on exception before calling future.get()
[英]Why calling future.get() retrieved from async leads to unexpected output order
考虑以下代码:
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <future>
std::mutex mutex;
int generate()
{
static int id = 0;
std::lock_guard<std::mutex> lock(mutex);
id++;
std::cout << id << '\n';
return id;
}
int main()
{
std::vector<std::future<int>> vec;
std::vector<int> result;
for(int i = 0; i < 10; ++i)
{
vec.push_back(std::async(std::launch::async,generate));
}
for(int i = 0; i < 10; ++i)
{
result.push_back(vec[i].get());
}
std::cout << "\n result:";
for(const auto res : result)
{
std::cout << res << " ";
}
}
产生以下 output:
1
2
3
4
5
6
7
8
9
10
result:1 2 3 6 4 5 7 8 9 10
如您所见, generate()
function 中的 output 具有正确的(从 1 到 10)顺序。 但是当迭代结果向量时,每次运行我都会得到不同的顺序。 为什么会发生这种情况,如何同步此类代码?
您在最终 output 中看到的是线程产生结果的顺序。
将这三个线程视为简化版本:
+- -+ +- -+ +- -+
Thread | 1 | | 2 | | 3 |
+- -+ +- -+ +- -+
Result | | | | | |
+- -+ +- -+ +- -+
现在,无论这些执行哪个命令并获取互斥锁,output 将是
1 2 3
因为id
是static
,第一个“储物柜”将其递增并打印“1”,然后第二个将其递增并打印“2”,依此类推。
让我们假设线程 3 首先获得互斥锁,然后是 1,然后是 2。
这导致了这种情况:
+- -+ +- -+ +- -+
Thread | 1 | | 2 | | 3 |
+- -+ +- -+ +- -+
Result | 2 | | 3 | | 1 |
+- -+ +- -+ +- -+
当您以“矢量顺序”打印结果时,您会看到
2 3 1
如果您希望线程以某种预定顺序执行,则需要进一步同步它们。
如果您立即解决未来,那么它将是按顺序排列的。 例如:
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <future>
std::mutex mutex;
int generate()
{
static int id = 0;
std::lock_guard<std::mutex> lock(mutex);
id++;
std::cout << id << '\n';
return id;
}
int main()
{
std::vector<std::future<int>> vec;
std::vector<int> result;
for(int i = 0; i < 10; ++i)
{
int result = std::async(std::launch::async,generate).get();
result.push_back(result);
}
std::cout << "\n result:";
for(const auto res : result)
{
std::cout << res << " ";
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.