Operaciones atómicas en lenguaje C

1. ¿Qué es una operación atómica?

Las operaciones atómicas son indivisibles y no serán interrumpidas por ninguna otra tarea o evento hasta que se ejecuten. Pueden considerarse como la unidad de operación más pequeña, que es la operación más pequeña que no provoca el acceso simultáneo a los datos durante la ejecución. Por lo tanto, se denominan operaciones atómicas. . La operación atómica más simple es intercambiar el valor de un registro y una dirección de memoria,

Las operaciones atómicas son la base para implementar el mecanismo de bloqueo. Mutex, spinlock, etc., todos tienen una operación atómica clave en su capa inferior. En los lenguajes de programación, generalmente hay dos casos:

  1. En un solo subproceso, las operaciones que se pueden completar en una sola instrucción se pueden considerar "operaciones atómicas" porque las interrupciones solo pueden ocurrir entre instrucciones.
  2. En subprocesos múltiples, las operaciones que no pueden ser interrumpidas por otros procesos (subprocesos) se denominan operaciones atómicas.

2. Por qué son necesarias las operaciones atómicas

En una máquina con procesadores multinúcleo, varias CPU pueden acceder simultáneamente al área de memoria para el mismo valor variable en un período corto de tiempo, lo que genera inestabilidad en el valor. Por ejemplo, en subprocesos múltiples, inicialice i = 0. Para la operación i++, si dos subprocesos la llaman al mismo tiempo, puede causar que el valor de i sea 2 cuando el primer subproceso lo usa.

El funcionamiento de i++ se divide en tres pasos:

  1. Acceso a la memoria, lea el valor de la variable i en el registro de la CPU;
  2. Hacer el valor en el registro +1;
  3. Escribe el valor en el registro de vuelta a la memoria.

Se puede ver que i++ no es una operación atómica.En un procesador de subprocesos múltiples sin protección de subprocesos, cada paso puede ser interrumpido por una interrupción externa, lo que afecta el valor de i. Si dos subprocesos llaman a i++ al mismo tiempo, i puede cambiar directamente de 0 a 2: el subproceso 1 aumenta i en 1 en el registro mientras que el subproceso 2 también realiza esta operación, por lo que cuando el valor de i en el registro se elimina a memoria, me agregaron 2 veces sin saberlo

3. Clasificación de las operaciones atómicas

3.1 Operaciones atómicas a nivel de hardware

Si se trata de un sistema de un solo procesador, cualquier operación puede considerarse una operación atómica siempre que se complete en una sola instrucción.

En el caso de múltiples procesadores, cualquier operación de instrucción única puede verse afectada. La CPU de la plataforma x86 proporciona un medio para bloquear el bus durante la ejecución de instrucciones para garantizar la atomicidad

3.2 Operaciones atómicas a nivel de software

La implementación de operaciones atómicas a nivel de software depende del soporte de operaciones atómicas de hardware.Por ejemplo, en el entorno Linux, el kernel proporciona dos conjuntos de interfaces de operaciones atómicas:

  1. operar con enteros
  2. operar en bits

4. API de operación atómica


// 将value加到*ptr上,结果更新到*ptr,并返回操作之前*ptr的值
type __sync_fetch_and_add (type *ptr, type value, ...) 

// 从*ptr减去value,结果更新到*ptr,并返回操作之前*ptr的值
type __sync_fetch_and_sub (type *ptr, type value, ...) 

// 将*ptr与value相或,结果更新到*ptr, 并返回操作之前*ptr的值
type __sync_fetch_and_or (type *ptr, type value, ...) 

// 将*ptr与value相与,结果更新到*ptr,并返回操作之前*ptr的值
type __sync_fetch_and_and (type *ptr, type value, ...) 

// 将*ptr与value异或,结果更新到*ptr,并返回操作之前*ptr的值
type __sync_fetch_and_xor (type *ptr, type value, ...) 

// 将*ptr取反后,与value相与,结果更新到*ptr,并返回操作之前*ptr的值
type __sync_fetch_and_nand (type *ptr, type value, ...) 

// 将value加到*ptr上,结果更新到*ptr,并返回操作之后新*ptr的值
type __sync_add_and_fetch (type *ptr, type value, ...) 

// 从*ptr减去value,结果更新到*ptr,并返回操作之后新*ptr的值
type __sync_sub_and_fetch (type *ptr, type value, ...) 

// 将*ptr与value相或, 结果更新到*ptr,并返回操作之后新*ptr的值
type __sync_or_and_fetch (type *ptr, type value, ...) 

// 将*ptr与value相与,结果更新到*ptr,并返回操作之后新*ptr的值
type __sync_and_and_fetch (type *ptr, type value, ...) 

// 将*ptr与value异或,结果更新到*ptr,并返回操作之后新*ptr的值
type __sync_xor_and_fetch (type *ptr, type value, ...) 

// 将*ptr取反后,与value相与,结果更新到*ptr,并返回操作之后新*ptr的值
type __sync_nand_and_fetch (type *ptr, type value, ...) 

// 比较*ptr与oldval的值,如果两者相等,则将newval更新到*ptr并返回true
bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...) 

// 比较*ptr与oldval的值,如果两者相等,则将newval更新到*ptr并返回操作之前*ptr的值
type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...) 

Supongo que te gusta

Origin blog.csdn.net/future_sky_word/article/details/128515269
Recomendado
Clasificación