std:: карта запись / чтение из нескольких потоков

Я хочу иметь возможность читать и писать в std::map с несколькими потоками. Есть ли способ сделать это без мьютекса (возможно, с std::atomic)?

Если нет, то какой самый простой способ сделать это в C++11?

2 ответов


если значения are std::atomic<>, вы можете изменить и читать их из произвольных потоков, но вам нужно как - то сохранить их адреса - указатели, ссылки или итераторы-и вам нужно знать, что никакой другой поток не будет вызывать erase на них....

тем не менее, даже атомарные значения не сделают безопасным изменение контейнера (например, вставка или стирание элементов), в то время как другие потоки также выполняют изменения или поиск или итерацию. Даже в "const" функции, как size(), empty(), begin(), end(), count(), и движение итератора-небезопасны, потому что операции мутации могут находиться в середине перемотки межузловых связей или обновления тех же данных.

для чего-нибудь большего, чем выше, вы будет нужен мьютекс.


для конкретного примера, скажем, вы вставили узел с std::string ключ "client_counter" - вы можете запустить поток, который получает итератор для этого элемента и делает атомарные обновления для счетчика, в то время как другие потоки могут find элемент и читать из него, но не должен erase его. У вас все еще могут быть другие узлы, вставленные в map, С другими обновителями и читателями, без дополнительной синхронизации с client_counter-обновление резьбы.


если вы не хотите использовать мьютекс, вам нужно дождаться параллельных контейнеров (C++17?). Если вы хотите использовать std::atomic операции внутри std::map тогда вы, вероятно, хотите сделать или найти в интернете полную реализацию параллельной atomic std::map.

если вы хотите использовать std::map of std::atomic тогда вам, вероятно, нужно знать, что это защитит только элементы внутри std::map, а не std::map в порядке.