OpenMP и STL-вектор
У меня есть код, для которого я хотел бы использовать OpenMP следующим образом:
std::vector<int> v(1000);
# pragma omp parallel for
for (int i = 0; i < 1000; ++i) {
v[i] = i;
}
Я читал, что векторный контейнер STL не является потокобезопасным в ситуации, когда несколько потоков записываются в один контейнер, что подразумевает, что мне нужно будет заблокировать вектор перед записью; однако мне также сказали, что операция записи выше как-то "атомарна", и поэтому условия гонки не выше. Может ли кто-нибудь прояснить это?
Ответы
Ответ 1
В этом конкретном примере это будет безопасно.
Причина в том, что вы не используете операции, которые могут привести к перераспределению. (например, push_back()
). Вы изменяете только содержимое отдельных элементов.
Обратите внимание, что вы можете законно сделать это:
std::vector<int> v(1000);
int *ptr = &v[0];
# pragma omp parallel for
for (int i = 0; i < 1000; ++i) {
ptr[i] = i;
}
Он становится небезопасным при запуске вызова таких методов, как push_back()
, pop_back()
, insert()
и т.д. из нескольких потоков.
Я также добавлю, что этот конкретный пример не подходит для parallelism, так как вряд ли удастся выполнить какую-либо работу. Но я предполагаю, что это просто ошарашенный пример с целью задать этот вопрос.
Ответ 2
Несколько чтения являются безопасными, но я бы рекомендовал избегать нескольких операций записи в один и тот же контейнер. Но вы можете писать в память, которую вы управляете самостоятельно. Разница с вектором заключается в том, что вы можете быть уверены, что память не будет изменена или перераспределена одновременно. В противном случае вы также можете использовать семафор, но это, вероятно, снизит эффективность, и если вы используете несколько, это может даже вызвать взаимоблокировки, если вы не работаете должным образом.