在对列表进行更改时,在std :: string和std :: list的boost :: unordered_map中进行线程安全

时间:2012-08-17 20:39:20

标签: c++ boost thread-safety unordered-map boost-unordered

我在性能关键的多线程环境中使用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容器替换怎么办?

感谢。

2 个答案:

答案 0 :(得分:1)

由于您只修改了包含的对象,而不是[unordered_]地图本身,因此您只需要锁定该包含的对象。如果将list更改为另一个序列(例如,deque或vector),则应保持相同 - 更改所包含对象的类型不会改变您只修改包含对象的事实,而不是包含它的地图。

答案 1 :(得分:1)

您不必在此执行任何锁定。如果确保密钥已经存在,那么访问它们是一种非变异操作,不需要锁定(只要没有其他人在变异)。每个列表都是独立的 - 只要没有其他人同时访问myMap["Apple"],你就是金色的。当然,您可以简单地使用更适合该任务的东西,例如可以从多个线程安全地变异的无锁列表,或者concurrent_unordered_map,例如您可以在TBB或PPL中找到。