c++ - 与 std::unordered_map 的数据竞争,尽管使用互斥锁定插入

标签 c++ concurrency stl containers unordered-map

我有一个 C++11 程序,它执行一些计算并使用 std::unordered_map 来缓存这些计算的结果。该程序使用多个线程,它们使用共享的 unordered_map 来存储和共享计算结果。

基于我对 unordered_map 和 STL 容器规范的阅读,以及 unordered_map thread safety ,似乎一个unordered_map,被多个线程共享,一次可以处理一个线程写入,但是一次可以处理多个读取器。

因此,我使用 std::mutex 来包装我对 map 的 insert() 调用,这样最多只有一个线程插入时间。

但是,我的 find() 调用没有互斥锁,因为从我的阅读来看,似乎许多线程应该能够同时读取。但是,我偶尔会遇到数据竞争(由 TSAN 检测到),这会在 SEGV 中表现出来。数据争用显然指向我上面提到的 insert()find() 调用。

当我将 find() 调用包装在互斥锁中时,问题就消失了。但是,我不想序列化并发读取,因为我试图让这个程序尽可能快。 (仅供引用:我正在使用 gcc 5.4 运行。)

为什么会这样?我对 std::unordered_map 的并发保证的理解不正确吗?

最佳答案

您仍然需要一个互斥体让您的读者将作者拒之门外,但您需要一个共享C++14 有一个 std::shared_timed_mutex可以与作用域锁一起使用 std::unique_lockstd::shared_lock像这样:

using mutex_type = std::shared_timed_mutex;
using read_only_lock  = std::shared_lock<mutex_type>;
using updatable_lock = std::unique_lock<mutex_type>;

mutex_type mtx;
std::unordered_map<int, std::string> m;

// code to update map
{
    updatable_lock lock(mtx);

    m[1] = "one";
}

// code to read from map
{
    read_only_lock lock(mtx);

    std::cout << m[1] << '\n';
}

关于c++ - 与 std::unordered_map 的数据竞争,尽管使用互斥锁定插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38061067/

相关文章:

linux - 查找 [主机] : no such host error in Go

java - 通过 Java 提交多个 hadoop 作业

java - 将 Dao 作为静态成员存储在类中是否安全?

c++ - C++判断分区是否为空

c# - 将确定性路径代码从 C# 转换为 C++

C++ memcpy 返回 true 没有任何变化

c++ - 如何比较 vector 和数组?

c++ - Google 可以模拟具有智能指针返回类型的方法吗?

c++ - 转换多个迭代器元素

c++ - 如何在下一个函数调用中从最后一个位置使用 STL 映射删除?