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

1.8k views Asked by At

I am using a boost::unordered_map<const std::string, std::list<TypeA> > in a performance critical multi-threaded environment. I understand that writing to STL containers isn't thread safe and the same goes for boost::unordered_map.

boost::unordered_map<const std::string, std::list<TypeA> > myMap;
// Added some elements to myMap        

Now, if I want to add or delete an element of type A to the list as , is it necessary is I just lock the entire map as opposed to locking the list that is being modified so that other threads can read/write the rest of the key value pairs?

// 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 

What if the list is replaced by another STL container?

Thanks.

2

There are 2 answers

0
Jerry Coffin On BEST ANSWER

Since you're modifying only the contained object, not the [unordered_]map itself, you should only have to lock that contained object. If you change the list to another sequence (e.g., deque or vector) the same should remain true -- changing the type of the contained object doesn't change the fact that you're only modifying that contained object, not the map that contains it.

0
Puppy On

You don't have to perform any locking here. If it's guaranteed that the keys already exist, then accessing them is a non-mutating operation which doesn't need locking (as long as nobody else is mutating). And each list is independent- as long as nobody else is accessing myMap["Apple"] at the same time, you're golden. Of course, you could simply use something more suited to the task, like a lockless list, which can be safely mutated from multiple threads, or a concurrent_unordered_map, such as you can find in TBB or PPL.