Atomic types
Contenidos |
Sintaxis
_Atomic
(
type-name
)
|
(1) | (desde C11) | |||||||
_Atomic
type-name
|
(2) | (desde C11) | |||||||
const
,
volatile
, y
restrict
, aunque a diferencia de otros calificadores, la versión atómica de
type-name
puede tener un tamaño, alineación y representación de objeto diferentes.
| type-name | - | cualquier tipo excepto array o función. Para (1) , type-name tampoco puede ser atomic o calificado cvr |
El encabezado <stdatomic.h> define muchos alias de tipos convenientes , desde atomic_bool hasta atomic_uintmax_t , que simplifican el uso de esta palabra clave con tipos incorporados y de biblioteca.
_Atomic const int* p1; // p es un puntero a un atomic const int const atomic_int* p2; // igual const _Atomic(int)* p3; // igual
Si la macro constante __STDC_NO_ATOMICS__ está definida por el compilador, la palabra clave _Atomic no está disponible.
Explicación
Los objetos de tipos atómicos son los únicos objetos que están libres de carreras de datos ; es decir, pueden ser modificados por dos hilos concurrentemente o modificados por uno y leídos por otro.
Cada objeto atómico tiene su propio
orden de modificación
asociado, que es un orden total de las modificaciones realizadas a ese objeto. Si, desde el punto de vista de algún hilo, la modificación
A
de algún atómico
M
sucede-antes
que la modificación
B
del mismo atómico
M
, entonces en el orden de modificación de
M
,
A
ocurre antes que
B
.
Tenga en cuenta que aunque cada objeto atómico tiene su propio orden de modificación, no existe un orden total único; diferentes hilos pueden observar modificaciones a diferentes objetos atómicos en órdenes diferentes.
Existen cuatro tipos de coherencia que están garantizados para todas las operaciones atómicas:
-
coherencia escritura-escritura
: Si una operación
Aque modifica un objeto atómicoMsucede-antes que una operaciónBque modificaM, entoncesAaparece antes queBen el orden de modificación deM. -
coherencia lectura-lectura
: Si una computación de valor
Ade un objeto atómicoMsucede antes que una computación de valorBdeM, yAtoma su valor de un efecto secundarioXsobreM, entonces el valor computado porBes o bien el valor almacenado porXo es el valor almacenado por un efecto secundarioYsobreM, dondeYaparece después deXen el orden de modificación deM. -
coherencia lectura-escritura
: Si una computación de valor
Ade un objeto atómicoMsucede-antes que una operaciónBsobreM, entoncesAtoma su valor de un efecto secundarioXsobreM, dondeXaparece antes queBen el orden de modificación deM. -
coherencia escritura-lectura
: Si un efecto secundario
Xsobre un objeto atómicoMsucede-antes que una computación de valorBdeM, entonces la evaluaciónBtoma su valor deXo de un efecto secundarioYque aparece después deXen el orden de modificación deM.
Algunas operaciones atómicas también son operaciones de sincronización; pueden tener semánticas de liberación adicionales, semánticas de adquisición o semánticas de consistencia secuencial. Consulte memory_order .
Operadores integrados de incremento y decremento y asignación compuesta son operaciones atómicas de lectura-modificación-escritura con ordenación secuencialmente consistente total (como si se usara memory_order_seq_cst ). Si se desean semánticas de sincronización menos estrictas, pueden usarse en su lugar las funciones de la biblioteca estándar .
Las propiedades atómicas solo son significativas para expresiones lvalue . La conversión de lvalue a rvalue (que modela una lectura de memoria desde una ubicación atómica a un registro de CPU) elimina la atomicidad junto con otros calificadores.
|
Esta sección está incompleta
Motivo: falta más información, revisar la interacción con memory_order y las páginas de la biblioteca atómica |
Notas
Acceder a un miembro de una estructura/unión atómica es un comportamiento indefinido.
El tipo de biblioteca sig_atomic_t no proporciona sincronización entre hilos ni ordenamiento de memoria, solo atomicidad.
Los tipos
volatile
no proporcionan sincronización entre hilos, ordenamiento de memoria ni atomicidad.
Se recomienda a las implementaciones garantizar que la representación de
_Atomic
(
T
)
en C sea la misma que la de
std
::
atomic
<
T
>
en C++ para todo tipo posible
T
. Los mecanismos utilizados para garantizar atomicidad y ordenamiento de memoria deben ser compatibles.
Palabras clave
Ejemplo
#include <stdatomic.h> #include <stdio.h> #include <threads.h> atomic_int acnt; int cnt; int f(void* thr_data) { for (int n = 0; n < 1000; ++n) { ++cnt; ++acnt; // for this example, relaxed memory order is sufficient, e.g. // atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed); } 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 8644
Referencias
- Estándar C23 (ISO/IEC 9899:2024):
-
- 6.7.2.4 Especificadores de tipo atómico (p: TBD)
-
- 7.17 Atomics <stdatomic.h> (p: TBD)
- Estándar C17 (ISO/IEC 9899:2018):
-
- 6.7.2.4 Especificadores de tipo atómico (p: 87)
-
- 7.17 Atomics <stdatomic.h> (p: 200-209)
- Estándar C11 (ISO/IEC 9899:2011):
-
- 6.7.2.4 Especificadores de tipo atómico (p: 121)
-
- 7.17 Atomics <stdatomic.h> (p: 273-286)
Véase también
| Biblioteca de soporte para concurrencia | |
|
Documentación de C++
para
atomic
|