Насколько я знаю, если два несинхронизированных потока обращаются к одному и тому же месту в памяти и хотя бы один пытается записать в него, вы получаете гонку данных.
При этом в следующем примере кода, что такое «то же самое место в памяти»:
std::unordered_map<int, std::string> map{{0, {}}, {1, {}}, {2, {}}, {3, {}},
{4, {}}, {5, {}}, {6, {}}, {7, {}}};
std::for_each(std::execution::par, map.begin(), map.end(),
[](auto &kvp) { kvp.second = std::to_string(kvp.first); });
Является ли это map
, означающим, что параллельное выполнение вводит гонку данных, или, как я подозреваю, каждое значение в kvp
означает, что код является потокобезопасным?
В этом случае std::for_each
не делает ничего, что может привести к состоянию гонки. Пока ваша лямбда, переданная std::for_each
, не делает что-то странное с побочными эффектами (например, доступ к другим элементам этой карты), все в порядке.
Большинство одновременных не-const
обращений к объектам стандартной библиотеки представляют собой гонки данных. Однако доступ через итераторы явно исключен:
Операции над итераторами, полученные путем вызова стандартного библиотечного контейнера или строковой функции-члена, могут получить доступ к базовому контейнеру, но не должны его изменять.
Поскольку они не изменяют доступ к объекту, сами по себе они не вызывают гонки данных.
Поскольку никакие другие параллельные операции в вашем коде не выполняют доступ для записи к самому объекту-контейнеру (только к его содержимому), в вашем коде отсутствуют гонки данных. То, что вы делаете внутри функции, может вызвать гонку данных, но это будет связано с манипулированием объектами в контейнере, а не с природой самого контейнера.
выглядит нормально для меня. Карта доступна только для чтения. Редактируются только строки внутри, и каждая строка редактируется одним потоком.