atomic_fetch_add, atomic_fetch_add_explicit
|
Definido en el encabezado
<stdatomic.h>
|
||
|
C atomic_fetch_add
(
volatile
A
*
obj, M arg
)
;
|
(1) | (desde C11) |
|
C atomic_fetch_add_explicit
(
volatile
A
*
obj, M arg,
memory_order
order
)
;
|
(2) | (desde C11) |
Reemplaza atómicamente el valor apuntado por
obj
con el resultado de la suma de
arg
al valor anterior de
obj
, y retorna el valor que
obj
contenía previamente. La operación es una operación de lectura-modificación-escritura. La primera versión ordena los accesos a memoria de acuerdo con
memory_order_seq_cst
, la segunda versión ordena los accesos a memoria de acuerdo con
order
.
Esta es una
función genérica
definida para todos los
tipos de objetos atómicos
A
. El argumento es un puntero a un tipo atómico volátil para aceptar direcciones de objetos atómicos tanto no volátiles como
volátiles
(por ejemplo, E/S mapeadas en memoria), y se preserva la semántica volátil cuando se aplica esta operación a objetos atómicos volátiles.
M
es o bien el tipo no atómico correspondiente a
A
si
A
es un tipo entero atómico, o
ptrdiff_t
si
A
es un tipo de puntero atómico.
No está especificado si el nombre de una función genérica es una macro o un identificador declarado con vinculación externa. Si se suprime una definición de macro para acceder a una función real (por ejemplo, entre paréntesis como ( atomic_fetch_add ) ( ... ) ), o un programa define un identificador externo con el nombre de una función genérica, el comportamiento no está definido.
Para los tipos de enteros con signo, la aritmética está definida para usar representación en complemento a dos. No hay resultados indefinidos. Para los tipos de puntero, el resultado puede ser una dirección indefinida, pero las operaciones por lo demás no tienen comportamiento indefinido.
Contenidos |
Parámetros
| obj | - | puntero al objeto atómico a modificar |
| arg | - | el valor a sumar al valor almacenado en el objeto atómico |
| order | - | el orden de sincronización de memoria para esta operación: se permiten todos los valores |
Valor de retorno
El valor mantenido previamente por el objeto atómico apuntado por
obj
.
Ejemplo
#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); // atómico ++cnt; // comportamiento indefinido, en la práctica se pierden algunas actualizaciones } 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); }
Salida posible:
The atomic counter is 10000 The non-atomic counter is 9511
Referencias
- Estándar C17 (ISO/IEC 9899:2018):
-
- 7.17.7.5 Las funciones genéricas atomic_fetch y modify (p: 208)
- Estándar C11 (ISO/IEC 9899:2011):
-
- 7.17.7.5 Las funciones genéricas atomic_fetch y modify (p: 284-285)
Véase también
|
sustracción atómica
(función) |
|
|
Documentación de C++
para
atomic_fetch_add
,
atomic_fetch_add_explicit
|
|