Я предполагаю, что под библиотекой Concurrency вы подразумеваете Microsoft Concurrency Runtime. Ваш вариант использования на самом деле является критическим разделом, и для этого Concurrency предоставляет concurrency::critical_section
, который является невозвращаемой блокировкой мьютекса:
using namespace concurrency;
class particle
{
double param1;
. . .
critical_section particle_lck;
. . .
};
Тогда критический раздел становится:
currentParticle->particle_lck.lock();
currentParticle->param1 += anything;
currentParticle->particle_lck.unlock();
Если вы предпочитаете ограниченный подход, используйте concurrency::critical_section::scoped_lock
:
{
critical_section::scoped_lock guard(currentParticle->particle_lck);
currentParticle->param1 += anything;
}
scoped_lock
- простая оболочка. Он принимает ссылку на объект critical_section
и вызывает lock()
в конструкторе, а затем unlock()
в деструкторе, поэтому он снимает блокировку, когда выходит из области видимости.
Как объяснено Джим Коун ie, использование блокировок для чего-то, что может быть сделано более эффективно с помощью операции atomi c, является излишним. В OpenMP обычно делают:
#pragma omp atomic update
currentParticle->param1 += anything;
Atomi c Операции в стандартном C ++ требуют использования специальных типов Atomi c, и они доступны только для типов с плавающей запятой, начиная с C +. +20, поэтому ваш код будет (при условии, что компилятор C ++ 20):
#include <atomic>
class particle
{
std::atomic<double> param1;
. . .
};
Обновление значения:
currentParticle->param1.fetch_add(anything, std::memory_order_relaxed);
Параллелизм не предоставляет свои собственные атомы c типов , Вместо этого он полагается на класс combinable
, чтобы обеспечить эквивалент для предложения reduction
OpenMP.