gpt4 book ai didi

c++ - 使用 concurrent_unordered_map 时崩溃

转载 作者:太空宇宙 更新时间:2023-11-04 12:13:44 25 4
gpt4 key购买 nike

我有一个concurrent_unordered_map。我使用 insert 函数(而不是其他函数)尝试同时插入到 map 中。然而,很多时候,这会在 insert 函数内部深处崩溃。这是一些代码:

class ModuleBase { 
public:
virtual Wide::Parser::AST* GetAST() = 0;
virtual ~ModuleBase() {}
};
struct ModuleContents {
ModuleContents() {}
ModuleContents(ModuleContents&& other)
: access(other.access)
, base(std::move(other.base)) {}
Accessibility access;
std::unique_ptr<ModuleBase> base;
};
class Module : public ModuleBase {
public:
// Follows Single Static Assignment form. Once it's been written, do not write again.
Concurrency::samples::concurrent_unordered_map<Unicode::String, ModuleContents> contents;
Wide::Parser::AST* GetAST() { return AST; }
Wide::Parser::NamespaceAST* AST;
};

这是我用来实际插入 map 的函数。还有更多,但它不接触 map ,只使用 insert 的返回值。

void CollateModule(Parser::NamespaceAST* module, Module& root, Accessibility access_level) {
// Build the new module, then try to insert it. If it comes back as existing, then we discard. Else, it was inserted and we can process.
Module* new_module = nullptr;
ModuleContents m;
{
if (module->dynamic) {
auto dyn_mod = MakeUnique<DynamicModule>();
dyn_mod->libname = module->libname->contents;
new_module = dyn_mod.get();
m.base = std::move(dyn_mod);
} else {
auto mod = MakeUnique<Module>();
new_module = mod.get();
m.base = std::move(mod);
}
new_module->AST = module;
m.access = access_level;
}
auto result = root.contents.insert(std::make_pair(module->name->name, std::move(m)));

这是根函数。它在不同输入上从多个线程并行调用,但具有相同的 root

void Collater::Context::operator()(Wide::Parser::NamespaceAST* input, Module& root) {
std::for_each(input->contents.begin(), input->contents.end(), [&](Wide::Parser::AST* ptr) {
if (auto mod_ptr = dynamic_cast<Wide::Parser::NamespaceAST*>(ptr)) {
CollateModule(mod_ptr, root, Accessibility::Public);
}
});
}

我不完全确定 wtf 是否正在进行。我有一点共享状态,而且我只能以原子方式访问它,那么为什么我的代码会死掉?

编辑:这其实完全是我自己的错。崩溃发生在 insert 行,我认为这是问题所在 - 但它不是。它根本与并发无关。我以错误的方式测试了 result 的返回值 - 即 true for value existed, false 对于 value did not exist,而标准为 insertion succeeded 定义 true - 即,value did not exist 。这严重扰乱了内存管理,导致崩溃——尽管我不知道它究竟是如何导致 unordered_map 代码崩溃的。一旦我插入了正确的否定,它就完美地工作了。这是因为我在跳过并发围栏之前没有正确测试单线程版本。

最佳答案

一种可能是由于移动语义问题导致崩溃。崩溃是由空指针解引用引起的吗?如果您在移动对象(例如 ModuleContents)后无意中访问了它,就会发生这种情况。

崩溃也可能是并发错误的结果。 concurrent_unordered_map 是线程安全的,因为插入和检索是原子的。但是,无论您在其中存储什么,都不会自动受到保护。因此,如果多个线程检索相同的 ModuleContents 对象,它们将共享 Module 内的 AST 树。我不确定哪些引用是可修改的,因为我没有看到任何 const 指针或引用。任何共享和可修改的东西都必须受到某种同步机制(例如,锁)的保护。

关于c++ - 使用 concurrent_unordered_map 时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8638086/

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