Какие операции являются потокобезопасными на std::map?
Предположим, у меня есть:
stl::map<std::string, Foo> myMap;
безопасна ли следующая функция потока?
myMap["xyz"] ?
Т.е. я хочу иметь эту гигантскую карту только для чтения, которая используется многими потоками; но я не знаю, если даже поиск это потокобезопасно.
Все написано в первый раз.
Затем, после этого, несколько потоков читают из него.
Я пытаюсь избежать блокировок, чтобы сделать это как можно быстрее. (яя возможна преждевременная оптимизация, я знаю)
6 ответов
Теоретически, контейнеры STL не являются потокобезопасными. На практике чтение безопасно, если контейнер не изменяется одновременно. то есть стандарт не содержит спецификаций о потоках. Следующая версия стандарта и IIUC гарантируют безопасное поведение только для чтения.
Если вы действительно обеспокоены, используйте отсортированный массив с двоичным поиском.
C++11 требует, чтобы все функции-члены были объявлены как const
Потокобезопасны для нескольких читателей.
призвание myMap["xyz"]
не является потокобезопасным, так как std::map::operator[]
не объявлен как const
, призвание myMap.at("xyz")
хотя потокобезопасен, так как std::map::at
объявлен как const
,
По крайней мере, в реализации Microsoft чтение из контейнеров является поточно- ориентированным ( ссылка).
Тем не мение, std::map::operator[]
может изменять данные и не объявляется const
, Вы должны вместо этого использовать std::map::find
, который const
, чтобы получить const_iterator
и разыменовывать это.
Теоретически, структуры данных и функции только для чтения не требуют каких-либо блокировок для обеспечения безопасности потоков. Это по своей сути потокобезопасно. При одновременном чтении из памяти не происходит скачек данных. Однако вы должны гарантировать безопасную инициализацию только одним потоком.
Как отметил Макс С., в основном реализация чтения элемента в карте похожа на myMap["xyz"]
не будет иметь операций записи. Если так, то это безопасно. Но, опять же, вы должны гарантировать, что нет потока, который изменяет структуру, кроме фазы инициализации.
Коллекции STL не являются поточно-ориентированными, но добавить в них безопасность потоков довольно просто.
Лучше всего создать потоковую оболочку вокруг рассматриваемой коллекции.
Это старый вопрос, но поскольку все существующие ответы, и в частности принятый, неверны, я добавляю еще один (извините, недостаточно представителей для комментариев).
Поскольку в OP явно упоминается доступ только для чтения (_ «гигантская карта только для чтения»),
Некоторые неконстантные функции рассматриваются в контексте потокобезопасности.
Пока только