Thread safety in boost::unordered_map of std::string and std::list, while making changes to list
-
27-06-2021 - |
문제
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.
해결책
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.
다른 팁
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.