我在性能关键的多线程环境中使用boost::unordered_map<const std::string, std::list<TypeA> >
。我理解写入STL容器不是线程安全的,boost::unordered_map
也是如此。
boost::unordered_map<const std::string, std::list<TypeA> > myMap;
// Added some elements to myMap
现在,如果我想在列表中添加或删除类型A的元素,是否有必要我只是锁定整个映射而不是锁定正在修改的列表,以便其他线程可以读/写其余的关键值对?
// Assuming there are pair with the keys "Apple" and "Orange" in myMap
A a, b;
myMap["Orange"].push_back(a) //Add an element to the list
myMap["Apple"].remove(b); //Remove an element
如果列表被另一个STL容器替换怎么办?
感谢。
答案 0 :(得分:1)
由于您只修改了包含的对象,而不是[unordered_]地图本身,因此您只需要锁定该包含的对象。如果将list
更改为另一个序列(例如,deque或vector),则应保持相同 - 更改所包含对象的类型不会改变您只修改包含对象的事实,而不是包含它的地图。
答案 1 :(得分:1)
您不必在此执行任何锁定。如果确保密钥已经存在,那么访问它们是一种非变异操作,不需要锁定(只要没有其他人在变异)。每个列表都是独立的 - 只要没有其他人同时访问myMap["Apple"]
,你就是金色的。当然,您可以简单地使用更适合该任务的东西,例如可以从多个线程安全地变异的无锁列表,或者concurrent_unordered_map
,例如您可以在TBB或PPL中找到。