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. Аргумент — указатель на изменчивый атомный тип для приема адресов как неизменчивых, так и изменчивых (например, отображаемых в памяти) атомных объектов, и семантика изменчивости сохраняется при применении этой операции к изменчивым атомным объектам. 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 и модификации (стр: 208)
- Стандарт C11 (ISO/IEC 9899:2011):
- 7.17.7.5 Общие функции atomic_fetch и модификации (стр: 284-285)
См. также
|
(C11) |
атомное вычитание (функция) |
Документация C++ для atomic_fetch_add, atomic_fetch_add_explicit |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/atomic/atomic_fetch_add