Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用并发\u无序\u映射崩溃_C++_Visual Studio 2010_C++11 - Fatal编程技术网

C++ 使用并发\u无序\u映射崩溃

C++ 使用并发\u无序\u映射崩溃,c++,visual-studio-2010,c++11,C++,Visual Studio 2010,C++11,我有一个并发\u无序\u映射。我使用insert函数(没有其他函数)尝试同时插入地图。但是,很多时候,这会在insert函数内部深处崩溃。下面是一些代码: class ModuleBase { public: virtual Wide::Parser::AST* GetAST() = 0; virtual ~ModuleBase() {} }; struct ModuleContents { ModuleContents() {} ModuleContents

我有一个
并发\u无序\u映射
。我使用
insert
函数(没有其他函数)尝试同时插入地图。但是,很多时候,这会在
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;
};
这是根函数。它是从不同输入上的多个线程并行调用的,但使用相同的

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);
    }
});
}
void Collater::Context::operator(){
std::for_each(输入->内容.begin(),输入->内容.end(),[&](宽::解析器::AST*ptr){
if(自动模式ptr=动态模式(ptr)){
CollateModule(mod_ptr,root,Accessibility::Public);
}
});
}
我不完全确定世界跆拳道联合会正在进行。我有一点共享状态,而且我只以原子方式访问它,那么为什么我的代码会消亡呢


编辑:这实际上完全是我自己的错。崩溃发生在
insert
行,我认为这是问题所在,但事实并非如此。它与并发性完全无关。我以错误的方式测试了
结果的返回值,即
值存在的
true
值不存在的
false
,而标准定义
插入成功的
true
,即
值不存在。这严重破坏了内存管理,导致了崩溃——虽然我不知道它到底是如何导致
unordered_map
代码崩溃的。一旦我插入了正确的否定,它就完美地工作了。这是因为我在跳过并发限制之前没有正确测试单线程版本。

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


崩溃也可能是并发错误造成的。
concurrent\u unordered\u映射
是线程安全的,因为插入和检索是原子的。但是,存储在其中的任何内容都不会自动受到保护。因此,如果多个线程检索相同的
模块内容
对象,它们将共享
模块
中的AST树。我不确定哪些引用是可修改的,因为我没有看到任何
const
指针或引用。任何共享和可修改的内容都必须受到某种同步机制(例如锁)的保护

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


崩溃也可能是并发错误造成的。
concurrent\u unordered\u映射
是线程安全的,因为插入和检索是原子的。但是,存储在其中的任何内容都不会自动受到保护。因此,如果多个线程检索相同的
模块内容
对象,它们将共享
模块
中的AST树。我不确定哪些引用是可修改的,因为我没有看到任何
const
指针或引用。任何共享和可修改的内容都必须受到某种同步机制(例如锁)的保护

你关于常数不正确的观点是正确的。然而,只有并发无序映射实际上是可变的。为什么不添加所有你认为是真的常量限定符,看看它是否编译。另外,请确保没有对这些常量对象的任何可变引用。我这样做只是为了验证我的假设,它是有效的。然而,我确实发现了实际问题。请参阅我的编辑以了解解决方案。您关于常量不正确的观点是正确的。然而,只有并发无序映射实际上是可变的。为什么不添加所有你认为是真的常量限定符,看看它是否编译。另外,请确保没有对这些常量对象的任何可变引用。我这样做只是为了验证我的假设,它是有效的。然而,我确实发现了实际问题。有关解决方案,请参见我的编辑。
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);
    }
});
}