Потокобезопасность в boost::unordered_map для std::string и std::list при внесении изменений в список

Я использую 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?

Спасибо.


person sank    schedule 17.08.2012    source источник


Ответы (2)


Поскольку вы изменяете только содержащийся объект, а не саму [unordered_]map, вам нужно заблокировать только этот содержащийся объект. Если вы измените list на другую последовательность (например, deque или vector), то же самое должно остаться верным - изменение типа содержащегося объекта не меняет того факта, что вы изменяете только этот содержащийся объект, а не карту, содержащую Это.

person Jerry Coffin    schedule 17.08.2012

Вам не нужно выполнять блокировку здесь. Если гарантировано, что ключи уже существуют, то доступ к ним является неизменяющей операцией, которая не нуждается в блокировке (пока никто другой не мутирует). И каждый список независим - пока никто другой не обращается к myMap["Apple"] в то же время, вы золотой. Конечно, вы могли бы просто использовать что-то более подходящее для этой задачи, например незаблокированный список, который можно безопасно изменять из нескольких потоков, или concurrent_unordered_map, который вы можете найти в TBB или PPL.

person Puppy    schedule 17.08.2012