gpt4 book ai didi

c++ - 使用 std::vector> 和 std::async 启动几个线程时的 Abort()

转载 作者:行者123 更新时间:2023-11-28 04:08:49 25 4
gpt4 key购买 nike

我使用 4 个线程使用 thread_local 创建一些对象内存池。

我正在使用 std::vector<std::future<int>>std::async(std::launch::async, function);调度线程和std::for_eacht.get取回它们的值(value)。这是代码:

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 Gandalf\n";
};

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 graveyard\n";
};


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';
}

(constructdestroy 在内部调用 allocatedeallocate。)我从终端得到了很多预期的输出,但在 abort 的某个地方被调用并且程序无法正常完成。我不知道为什么。我相信 t.get()调用以 std::async 启动的线程会自动调用 .join太对了吧?

使用 C++17 和 Visual Studio 2017。我做错了什么?

最佳答案

你有未定义的行为。您在无效的 future 调用 get。您的 future vector 的前 4 个项目为空 future。只有当 future::valid 返回 true 时,才能调用 get

这行你怎么看

std::vector<std::future<int>> vec{ 4 };

是吗?

Default constructor. Constructs a std::future with no shared state. After construction, valid() == false.

here您可以阅读调用 future::get 时发生的情况:

The behavior is undefined if valid() is false before the call to this function.

关于c++ - 使用 std::vector<std::future<int>> 和 std::async 启动几个线程时的 Abort(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58233802/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com