Потокобезопасность в 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?

Благодарю.

2 ответа

Решение

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

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

Другие вопросы по тегам