在 boost::unordered_map 的 std::string 和 std::list 中提供线程安全,同时对

Thread safety in boost::unordered_map of std::string and std::list, while making changes to list

本文关键字:std 线程 安全 unordered boost map string list      更新时间:2023-10-16

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

谢谢。

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

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