concurrent_unordered_map
이 있습니다. 나는 insert
함수 (그리고 다른 함수)를 사용하여지도에 동시에 삽입하려고합니다. 그러나 여러 번이 기능은 내부의 insert
내부에서 심하게 손상됩니다. 다음은 몇 가지 코드입니다.concurrent_unordered_map을 사용하여 충돌이 발생했습니다.
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;
};
이것은 실제로지도에 삽입하는 데 사용하는 기능입니다. 더 많은 것이 있지만지도에 손대지 않으며 반환 값인 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);
}
});
}
전적으로 잘 모르겠습니다. 공유 상태의 비트가 하나 있으며 원자 적으로 만 액세스 할 수 있습니다. 그렇다면 코드가 왜 죽어 가고 있습니까?
편집 : 이것은 실제로 내 자신의 잘못입니다. 충돌은 insert
줄에 있었는데, 나는 문제라고 생각했지만 - 은이 아니 었습니다. 동시성과 관련이 전혀 없습니다. 나는 result
의 잘못된 방향으로 반환 값을 테스트 주위 - 즉, true
표준이 insertion succeeded
에 대한 true
정의하는 반면, value did not exist
에 대한 false
, value existed
에 - 즉, value did not exist
을. 이것은 메모리 관리를 크게 망가뜨려 충돌을 일으켰습니다. 코드가 정확히 어떻게 발생했는지는 알 수 없습니다. 올바른 부정을 삽입하면 완벽하게 작동합니다. 이는 동시 울타리를 점프하기 전에 단일 스레드 버전을 제대로 테스트하지 않았기 때문에 나타났습니다.
const-correctness가 부족하다는 점에 관해서는 좋은 생각입니다. 그러나'concurrent_unordered_map '만 실제로 * 변경할 수 있습니다 *. – Puppy
사실이라고 생각하는 모든 const 한정자를 추가하고 컴파일하는지 확인하지 않는 이유는 무엇입니까? 또한 해당 const 개체에 대한 변경 가능한 참조가 없는지 확인하십시오. –
나는 내 가정을 실제로 검증하기 위해 그 일을했다. 그러나, 나는 실제 문제를 발견했다. 솔루션에 대한 편집을 참조하십시오. – Puppy