atomic_fetch_add, atomic_fetch_add_explicit
|
Определено в заголовочном файле
<stdatomic.h>
|
||
|
C atomic_fetch_add
(
volatile
A
*
obj, M arg
)
;
|
(1) | (начиная с C11) |
|
C atomic_fetch_add_explicit
(
volatile
A
*
obj, M arg,
memory_order
order
)
;
|
(2) | (начиная с C11) |
Атомарно заменяет значение, на которое указывает
obj
, результатом сложения
arg
со старым значением
obj
, и возвращает значение
obj
, которое хранилось ранее. Операция является операцией чтения-изменения-записи. Первая версия упорядочивает доступ к памяти в соответствии с
memory_order_seq_cst
, вторая версия упорядочивает доступ к памяти в соответствии с
order
.
Это
обобщённая функция
, определённая для всех
атомарных типов объектов
A
. Аргументом является указатель на volatile атомарный тип для принятия адресов как не-volatile, так и
volatile
(например, отображаемых в памяти I/O) атомарных объектов, и семантика volatile сохраняется при применении этой операции к volatile атомарным объектам.
M
является либо неатомарным типом, соответствующим
A
, если
A
является атомарным целочисленным типом, либо
ptrdiff_t
, если
A
является атомарным типом указателя.
Не определено, является ли имя обобщённой функции макросом или идентификатором, объявленным с внешней линковкой. Если определение макроса подавляется для доступа к реальной функции (например, заключено в скобки как ( atomic_fetch_add ) ( ... ) ), или программа определяет внешний идентификатор с именем обобщённой функции, поведение не определено.
Для знаковых целочисленных типов арифметика определена с использованием дополнительного кода. Неопределённых результатов не существует. Для типов указателей результат может быть неопределённым адресом, но в остальном операции не имеют неопределённого поведения.
Содержание |
Параметры
| obj | - | указатель на атомарный объект для модификации |
| arg | - | значение для добавления к значению, хранящемуся в атомарном объекте |
| order | - | порядок синхронизации памяти для этой операции: допустимы все значения |
Возвращаемое значение
Значение, которое ранее содержалось в атомарном объекте, на который указывает
obj
.
Пример
#include <stdio.h> #include <threads.h> #include <stdatomic.h> atomic_int acnt; int cnt; int f(void* thr_data) { for(int n = 0; n < 1000; ++n) { atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed); // atomic ++cnt; // undefined behavior, in practice some updates missed } return 0; } int main(void) { thrd_t thr[10]; for(int n = 0; n < 10; ++n) thrd_create(&thr[n], f, NULL); for(int n = 0; n < 10; ++n) thrd_join(thr[n], NULL); printf("The atomic counter is %u\n", acnt); printf("The non-atomic counter is %u\n", cnt); }
Возможный вывод:
The atomic counter is 10000 The non-atomic counter is 9511
Ссылки
- Стандарт C17 (ISO/IEC 9899:2018):
-
- 7.17.7.5 Универсальные функции atomic_fetch и modify (стр. 208)
- Стандарт C11 (ISO/IEC 9899:2011):
-
- 7.17.7.5 Универсальные функции atomic_fetch и modify (стр: 284-285)
Смотрите также
|
атомарное вычитание
(функция) |
|
|
Документация C++
для
atomic_fetch_add
,
atomic_fetch_add_explicit
|
|