C Language
Atomística
Buscar..
Sintaxis
-
#ifdef __STDC_NO_ATOMICS__
-
# error this implementation needs atomics
-
#endif
-
#include <stdatomic.h>
- sin firma _Atomic counter = ATOMIC_VAR_INIT (0);
Observaciones
La atómica como parte del lenguaje C es una característica opcional que está disponible desde C11.
Su propósito es garantizar el acceso sin carreras a las variables que se comparten entre diferentes subprocesos. Sin la calificación atómica, el estado de una variable compartida sería indefinido si dos subprocesos acceden a ella simultáneamente. Por ejemplo, una operación de incremento ( ++
) podría dividirse en varias instrucciones del ensamblador, una lectura, la adición en sí y una instrucción de almacenamiento. Si otro hilo estuviera realizando la misma operación, sus dos secuencias de instrucciones podrían estar entrelazadas y dar lugar a un resultado inconsistente.
Tipos: Todos los tipos de objetos, con excepción de los tipos de matriz, pueden calificarse con
_Atomic
.Operadores: Se garantiza que todos los operadores de lectura-modificación-escritura (por ejemplo,
++
o*=
) en estos son atómicos.Operaciones: hay algunas otras operaciones que se especifican como funciones genéricas de tipo, por ejemplo,
atomic_compare_exchange
.Subprocesos: se garantiza que el acceso a ellos no producirá una carrera de datos cuando se acceda a ellos mediante diferentes subprocesos.
Manejadores de señales: los tipos atómicos se denominan sin bloqueo si todas las operaciones en ellos son sin estado. En ese caso, también pueden usarse para tratar cambios de estado entre el flujo de control normal y un manejador de señales.
Solo hay un tipo de datos que está garantizado como libre de bloqueo:
atomic_flag
. Este es un tipo mínimo en el que las operaciones están diseñadas para asignarse a instrucciones de hardware de prueba y configuración eficientes.
Otros medios para evitar las condiciones de carrera están disponibles en la interfaz de subprocesos de C11, en particular un tipo de mutex mtx_t
para excluir mutuamente que los subprocesos accedan a datos críticos o secciones críticas de código. Si no se dispone de atomics, estos deben usarse para prevenir razas.
atómicos y operadores
Se puede acceder a las variables atómicas simultáneamente entre diferentes hilos sin crear condiciones de carrera.
/* a global static variable that is visible by all threads */
static unsigned _Atomic active = ATOMIC_VAR_INIT(0);
int myThread(void* a) {
++active; // increment active race free
// do something
--active; // decrement active race free
return 0;
}
Todas las operaciones de valor l (operaciones que modifican el objeto) que están permitidas para el tipo base están permitidas y no conducirán a condiciones de carrera entre los diferentes subprocesos que acceden a ellas.
- Las operaciones en objetos atómicos son generalmente órdenes de magnitud más lentas que las operaciones aritméticas normales. Esto también incluye operaciones simples de carga o almacenamiento. Así que solo deberías usarlos para tareas críticas.
- Operaciones aritméticas habituales y asignación como
a = a+1;
son, de hecho, tres operaciones ena
: primero una carga, luego adición y finalmente una tienda. Esto no es raza libre. Sólo la operacióna += 1;
ya++;
son.