Какие операции являются потокобезопасными на std :: map? - PullRequest
14 голосов
/ 31 января 2010

Предположим, у меня есть:

stl::map<std::string, Foo> myMap;

является ли следующая функция безопасной для потока?

myMap["xyz"] ?

Т.е. я хочу иметь эту гигантскую карту только для чтения, которая является общей для многих потоков;но я не знаю, является ли поиск даже потокобезопасным.


Сначала все записывается в один раз.

Затем после этого из него читают несколько потоков.

Я пытаюсь избежать блокировок, чтобы сделать это максимально быстрым.(яя возможна преждевременная оптимизация, я знаю)

Ответы [ 5 ]

11 голосов
/ 04 мая 2013

C ++ 11 требует, чтобы все функции-члены, объявленные как const, были поточно-ориентированными для нескольких читателей.

Вызов myMap["xyz"] не является поточно-ориентированным, так как std::map::operator[] не объявлен как const. Вызов myMap.at("xyz") является поточно-ориентированным, так как std::map::at объявлен как const.

11 голосов
/ 31 января 2010

Теоретически ни один контейнер STL не является поточно-ориентированным. На практике чтение безопасно, если контейнер не изменяется одновременно. то есть стандарт не содержит спецификаций о потоках. Следующая версия стандарта и IIUC гарантируют безопасное поведение только для чтения.

Если вы действительно обеспокоены, используйте отсортированный массив с двоичным поиском.

6 голосов
/ 31 января 2010

По крайней мере, в реализации Microsoft чтение из контейнеров является поточно-ориентированным ( ссылка ).

Однако std::map::operator[] может изменять данные и не объявляется const. Вместо этого вы должны использовать std::map::find, то есть const, чтобы получить const_iterator и разыменовать его.

4 голосов
/ 31 января 2010

Теоретически, структуры данных и функции только для чтения не требуют каких-либо блокировок для обеспечения безопасности потоков.Это по своей сути потокобезопасно.* * * * * * * * При одновременном чтении из памяти нет скачек данных .Тем не менее, вы должны гарантировать безопасную инициализацию только одним потоком.

Как отметил Макс С., в основном реализация чтения элемента в карте, подобного myMap["xyz"], не будет иметь операций записи.Если так, то это безопасно.Но, опять же, вы должны гарантировать, что нет потока, который изменяет структуру, кроме фазы инициализации.

1 голос
/ 31 января 2010

Коллекции STL не являются поточно-ориентированными, но довольно просто добавить безопасность потоков к одному.

Лучше всего создать безопасную оболочку вокруг рассматриваемой коллекции.

...