使用 std::vector<std::future<int>> 和 std::async 启动几个线程时中止
Abort() when starting up a few threads with std::vector<std::future<int>> and std::async
我正在使用 4 个线程使用thread_local
内存池创建一些对象。
我正在使用std::vector<std::future<int>>
和std::async(std::launch::async, function);
来调度线程,并与t.get
std::for_each
以恢复它们的价值。代码如下:
struct GameObject
{
int x_, y_, z_;
int m_cost;
GameObject() = default;
GameObject(int x, int y, int z, int cost)
: x_(x), y_(y), z_(z), m_cost(cost)
{}
};
struct Elf : GameObject
{
Elf() = default;
Elf(int x, int y, int z, int cost)
: GameObject(x, y, z, cost)
{
std::cout << "Elf created" << 'n';
}
~Elf() noexcept
{
std::cout << "Elf destroyed" << 'n';
}
std::string m_cry = "nA hymn for Gandalfn";
};
struct Dwarf : GameObject
{
Dwarf() = default;
Dwarf(int x, int y, int z, int cost)
: GameObject(x, y, z, cost)
{
std::cout << "dwarf created" << 'n';
}
~Dwarf() noexcept
{
std::cout << "dwarf destroyed" << 'n';
}
std::string m_cry = "nFind more cheer in a graveyardn";
};
int elvenFunc()
{
thread_local ObjectPool<Elf> elvenPool{ 229 };
for (int i = 0; i < elvenPool.getSize(); ++i)
{
Elf* elf = elvenPool.construct(i, i + 1, i + 2, 100);
std::cout << elf->m_cry << 'n';
elvenPool.destroy(elf);
}
thread_local std::promise<int> pr;
pr.set_value(rand());
return 1024;
}
int dwarvenFunc()
{
thread_local ObjectPool<Dwarf> dwarvenPool{ 256 };
for (int i = 0; i < dwarvenPool.getSize(); ++i)
{
Dwarf* dwarf = dwarvenPool.construct(i - 1, i - 2, i - 3, 100);
std::cout << dwarf->m_cry << 'n';
dwarvenPool.destroy(dwarf);
}
thread_local std::promise<int> pr;
pr.set_value(rand());
return 2048;
}
int main()
{
std::ios_base::sync_with_stdio(false);
srand(time(0));
std::vector<std::future<int>> vec{ 4 };
vec.emplace_back(std::async(std::launch::async, elvenFunc));
vec.emplace_back(std::async(std::launch::async, elvenFunc));
vec.emplace_back(std::async(std::launch::async, dwarvenFunc));
vec.emplace_back(std::async(std::launch::async, dwarvenFunc));
int term = 0;
try
{
std::for_each(std::execution::par, vec.begin(), vec.end(), [&term](std::future<int>& t)
{
auto ret = t.get();
std::cout << "thread brought me " << ret << 'n';
term += ret;
});
}
catch (const std::exception& ex)
{
std::cout << ex.what() << 'n';
}
std::cout << "Final word = " << term << 'n';
}
(construct
和destroy
在内部调用allocate
和deallocate
。我从终端获得了很多预期的输出,但是在某个地方abort
被调用并且程序无法正常完成。我找不到为什么。我相信以 std::async 启动的线程的t.get()
调用也会自动调用.join
对吗?
使用 C++17 和 Visual Studio 2017。我做错了什么?
你有未定义的行为。您在无效的未来调用get
。您的期货向量有前 4 个项目作为空future
。 仅当future::valid
返回 true 时,才能调用get
。
你怎么看这句话
std::vector<std::future<int>> vec{ 4 };
是否 ?
默认构造函数。构造一个没有共享状态的 std::future。 构造后,valid(( == 假。
在这里,您可以阅读调用future::get
时会发生什么:
如果在调用此行为之前 valid(( 为 false,则行为未定义 功能。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 是std :: set&lt; std :: future&gt;不可能存在
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- 使用 std::vector<boost::shared_ptr<Base_Class>> 或 boost::p tr_vector 的性能注意事项是什么<Base>
- std::map<std::set, double> AND std:<long>map< std::p air<long, long>, double>
- 如何获取std::vector<DMatch>