многоплатформенный атомарный инкремент

#c #boost #synchronization #atomic #multiplatform

#c #повышение #синхронизация #атомарный #многоплатформенный

Вопрос:

До std::atomic тех пор, пока он не будет доступен, каков мультиплатформенный (Windows и Linux) способ атомарного увеличения переменной?

В настоящее время я использую boost::detail::atomic_count , но он находится в boost::detail пространстве имен, и я не знаю, безопасно ли его использовать.

Комментарии:

1. Вы смотрели на рассматриваемый в настоящее время Boost. Атомарная библиотека?

2. std::atomic уже доступен. Нет?

3. MSVC и GCC теперь имеют поддержку std::atomic . Также есть stdthread.co.uk

Ответ №1:

Многоплатформенный, но специфичный для компилятора способ заключается в использовании GCC __sync_fetch_and_add .

Или определите такую функцию самостоятельно с помощью небольшой условной компиляции:

 #ifdef __GNUC__
#define atomic_inc(ptr) __sync_fetch_and_add ((ptr), 1)
#elif defined (_WIN32)
#define atomic_inc(ptr) InterlockedIncrement ((ptr))
#else
#error "Need some more porting work here"
#endif
  

Комментарии:

1. __sync_fetch_and_add и MSVC InterlockedIncrement не эквивалентны по их возвращаемым типам. __sync_fetch_and_add возвращает предыдущее значение ptr, а InterlockedIncrement возвращает результирующее значение увеличенного ptr. Что вам нужно использовать, так это «__sync_add_и_fetch», чтобы быть эквивалентными / взаимозаменяемыми.

2. Кроме того, InterlockedIncrement только для 32-разрядных значений.

Ответ №2:

Используйте InterlockedExchangeAdd вместо InterlockedIncrement — это полный аналог, с __sync_fetch_и_add;

 #ifdef __GNUC__
#define atomic_inc(ptr) __sync_fetch_and_add ((ptr), 1)
#elif defined (_WIN32)
#define atomic_inc(ptr) InterlockedExchangeAdd ((ptr), 1)
#else
#error "Need some more porting work here"
#endif
  

Вы можете найти проверенные аналоги вызовов msvc / gcc здесь (x86)