2010-01-31 3 views
13

Suppoes у меня есть:Какие операции являются потокобезопасными на std :: map?

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

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

myMap["xyz"] ? 

I.e. Я хочу иметь эту гигантскую карту только для чтения, которая распределяется между многими потоками; но я не знаю, можно ли даже искать его в потоковом режиме.

Спасибо!

EDIT:

Все написано один раз первым.

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

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

ответ

11

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

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

2

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

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

6

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

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

+0

Для того, чтобы в контейнере было что-то, нужно его записать. Следовательно, проблема безопасности потоков ... –

+1

Вопросы задают, что мы смотрим карту только для чтения.Я предполагаю, что это означает, что он заполнен полностью в одном потоке, прежде чем читать из нескольких потоков. –

4

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

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

7

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

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