is `std :: map <..> a;blah = a [abcd]; `потокобезопасен, если abcd не был создан до этого вызова? - PullRequest
2 голосов
/ 26 августа 2011

Итак, мы создали карту.Мы хотим получить some_type blah = map_variable[some_not_inserted_yet_value], это вызовет добавление нового элемента на карту, если он не был создан ранее.Так что мне интересно, действительно ли read является поточно-ориентированным с std::map или возможно только потоковое исполнение safly try{ ...find(..)->second...?

Ответы [ 4 ]

3 голосов
/ 26 августа 2011

Идея, что вызов find(...)->second является потокобезопасным, очень зависит от вашего взгляда на безопасность потока. Если вы просто имеете в виду, что он не рухнет, тогда, пока никто не мутирует в словаре в то время, когда вы его читаете, я полагаю, вы в порядке.

Тем не менее, независимо от того, каковы ваши минимальные требования безопасности потоков, вызов метода operator[] по своей природе не поточно-безопасен, поскольку может изменять коллекцию.

Если у метода нет перегрузки const, это означает, что он может изменять объект, поэтому, если в документации не указано, что методы являются поточно-ориентированными, метод вряд ли будет.

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

2 голосов
/ 26 августа 2011

Если вы на 100% уверены, что карта содержит ключ, то она технически поточнобезопасна, если все остальные потоки также только вызывают методы только для чтения на карте. Обратите внимание, что const версия map<k,v>::operator[](const k&).

отсутствует.

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

map<k,v>::const_iterator match = mymap.find(key);
if ( match != mymap.end() ) {
    // found item.
}

Как указано выше, это применимо только в том случае, если весь параллельный доступ только для чтения . Один из способов гарантировать это - использовать блокировку читателей-писателей .

Обратите внимание, что в C ++ 03 нет упоминания о потоках в стандарте, так что даже это не гарантируется поточно-ориентированным. Обязательно ознакомьтесь с документацией вашей реализации.

1 голос
/ 26 августа 2011

Стандартные библиотечные контейнеры не имеют понятия о безопасности потоков.Вы должны синхронизировать одновременный доступ на чтение / запись к контейнеру самостоятельно.

try не имеет ничего общего с многопоточностью.Используется для обработки исключений.

find не выдает исключение, если ключ не найден.Если ключ не найден, функция find возвращает end() итератор карты.

0 голосов
/ 26 августа 2011

Вы правы, operator[] не является "потокобезопасным", поскольку может изменять контейнер. Вы должны использовать метод find и сравнить результат с std::map::end, чтобы увидеть, нашел ли он предмет. (Также обратите внимание, что find имеет версию const, а operator[] нет).

Как уже говорили другие, версия C ++ до C ++ 11 не имеет понятия о потоках или безопасности потоков. Тем не менее, вы можете чувствовать себя в безопасности, используя find без синхронизации, потому что он не меняет контейнер, поэтому он выполняет только операции чтения (если у вас нет странной реализации, поэтому обязательно проверьте документы). Как и в случае большинства контейнеров, чтение из него из разных потоков не принесет никакого вреда, однако запись в него может привести.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...