Kul*_*007 6 c++ concurrency containers stl unordered-map
我有一个C++ 11程序,它执行一些计算并使用a std::unordered_map来缓存那些计算的结果.该程序使用多个线程,并使用共享unordered_map来存储和共享计算结果.
基于我对unordered_mapSTL容器规范的读取以及unordered_map线程安全性,似乎unordered_map多个线程共享的一个线程可以一次处理一个线程,但一次只能处理许多读者.
因此,我使用a std::mutex将我的insert()调用包装到地图中,因此一次最多只插入一个线程.
但是,我的find()调用没有互斥,因为从我的阅读来看,似乎许多线程应该能够立即读取.但是,我偶尔会得到数据竞赛(由TSAN检测到),在SEGV中表现出来.这些数据清楚地赛点的insert(),并find()调用我上面提到的.
当我find()用互斥锁包装调用时,问题就消失了.但是,我不想序列化并发读取,因为我试图尽可能快地使这个程序.(仅供参考:我正在使用gcc 5.4.)
为什么会这样?我对并发保证的理解std::unordered_map不正确吗?
您仍然需要一个mutex供读者使用的工具,以将作者拒之门外,但您需要一个共享的工具。C++14具有一个std :: shared_timed_mutex,您可以将其与范围锁std :: unique_lock和std :: 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';
}
Run Code Online (Sandbox Code Playgroud)