C ++ STD Atomic

C ++ STD Atomic

Usamos el "STD Atomic" si queremos retener la atomicidad de la operación en C++. La atomicidad es el concepto con el que tenemos que tratar cuando trabajamos en operaciones/aplicaciones multiproceso, donde incluso las funciones simples, como leer y escribir en la ejecución simultáneamente, pueden crear problemas o comportamientos indefinidos en el código. Para lidiar con tal situación, C ++ ha definido la biblioteca "STD :: Atomic" que garantiza una consistencia que es lo suficientemente secuencial para la ejecución de la lectura y la escritura para varios objetos distintos que representa el comportamiento bien definido. Si un hilo está escribiendo en algún momento, el otro hilo está leyendo en ese momento.

Procedimiento:

Este artículo explorará qué es la atomicidad y cómo podemos usar los conceptos de STD Atomic para lidiar con los comportamientos indefinidos en nuestros códigos. Discutiremos las diversas funciones de STD Atomic e implementaremos los diversos ejemplos para STD Atomic. La función bajo el STD Atomic que implementaremos en los diferentes ejemplos se dan de la siguiente manera:

  • Lectura y escritura de valores más simples
  • Liberar y adquirir pedidos con memoria (modelo)
  • Modelo de intercambio
  • Operación de búsqueda

Lectura y escritura de valores más simples

Creemos una aplicación múltiple en este ejemplo donde creamos dos hilos: un hilo para leer los valores y el otro hilo para escribir los valores. Con la ayuda de este ejemplo, trataremos de obtener el concepto de Atomics STD, cuáles son los comportamientos indefinidos mientras ejecutan las aplicaciones multiproceso y cómo el Atomic STD elimina los comportamientos indefinidos.

Para eso, simplemente iniciamos el código asignando dos valores diferentes a dos variables diferentes de tipo entero. Primero, inicializamos la variable "A" y "B" con los tipos de datos enteros. Luego, creamos la función que se escribe en el vacío. En esta función, asignamos los valores a "A" y "B", E.gramo. 25 y 20, respectivamente.

Luego, creamos la función de lectura. En la función de lectura, los valores de "A" y "B" se leen con el "std :: cout <

Producción:

La salida de este ejemplo muestra el comportamiento indefinido de la aplicación ya que la salida del código es 0 o 10. Esto sucedió porque los hilos se estaban ejecutando simultáneamente y el comando de lectura podría haberse realizado durante la ejecución del comando de escritura. De esta manera, obtuvimos un resultado incompleto en la salida.

El STD Atomic puede resolver este problema y puede hacer que los comportamientos indefinidos en la aplicación estén bien definidos. Para implementar esto, simplemente hacemos un pequeño cambio al inicializar y establecer los valores y tipos de datos de las variables definidas utilizando "STD :: Atomic". Definimos la variable "A" y "B" como las variables atómicas por "STD :: Nombre de la variable atómica". También hacemos un pequeño cambio en la función de escritura donde, anteriormente, simplemente asignamos los valores a A y B utilizando el operador de asignación "=". Pero aquí, asignamos los valores usando el "Nombre de la variable. Método de almacenar (valor) ". Usamos el "Nombre de la variable. load () ”en la función de lectura. El resto es el mismo que en el ejemplo anterior.

Los valores en la salida se leen y escriben de manera bien definida. Y el múltiplo también es compatible aquí.

Liberar y adquirir pedidos con memoria (modelo)

El modelo de memoria puede tener un gran impacto en las funciones de lectura y escritura del STD Atomic. El modelo de memoria es una función predeterminada que se asegura de una consistencia de pedidos secuenciales. Uno de los modelos atómicos más interesantes es el modelo de lanzamiento y adquirir donde podemos almacenar el lanzamiento del orden de memoria para el primer hilo y el orden de memoria adquirido para el segundo hilo, lo que significa que cualquier almacenamiento/escritura se realiza atómica o no atómica. primero en el primer hilo antes del segundo hilo, yo.mi. carga.

Entonces, en el ejemplo, incluso podemos cambiar la variable atómica "A" a no atómica y la segunda variable "B" se mantiene atómica. En la función de escritura, almacenamos la variable no atómica "A" simplemente asignándolo cualquier valor, e.gramo. 30. Y almacenamos correctamente el valor de la variable atómica "B" usando "B. almacenar (valor, std :: memoria_order_release) ". Lo mismo se realiza en la función de lectura también donde usamos el "std :: cout <

Producción:

La atomicidad de la operación todavía se mantiene con el modelo de memoria de liberación y adquirida incluso cuando teníamos una variable X no atómica. Esto sucedió debido a la Y (atómica.almacenar) que se aseguró de que el mantenimiento de la consistencia secuencial.

Modelo de intercambio

Intercambiar significa cuando intercambiamos el valor de una variable (atómica) a otro valor. A cambio, el valor se intercambia primero y luego se devuelve el valor anterior que está cambiando por el nuevo. Una vez que se intercambia el valor, se refleja en cada operación posterior a ese valor. Implementemos este intercambio de variables atómicas con la ayuda de un ejemplo.

En este ejemplo, primero presentamos la variable atómica global Foobar que tiene algún valor igual a "15". En general, hacemos un hilo como hilo1 y le asignamos un valor entero igual a 2. Luego, en el bucle for, establecemos el índice de 0 a 100 veces. Luego, reemplazamos el valor de la variable Foobar a 2 usando "Foobar. valor de cambio)". Después de eso, salimos del bucle y cargamos el valor de la variable Foobar para imprimirlo. Después de cargar el valor de Foobar, ahora intercambiamos su valor con 18 por el ".Método de intercambio (valor a reemplazar) ". Y luego, nuevamente, cargue los valores del Foobar y muestrelos utilizando el método de impresión.

Aquí en este ejemplo, el hilo tiene que intercambiar los valores por cien veces y el valor de Foobar se intercambia de 15 a 28. Cualquier operación después de este intercambio devuelve este mismo valor que se puede ver en la salida.

Buscar

Buscar es lo mismo que la función de intercambio que escribe los valores y devuelve los valores obtenidos previamente. Esta operación obtiene el valor que se almacena antes de que se aplique cualquier operación. Ahora, implementamos la obtención de disposición y el restar en este ejemplo. Definimos una variable atómica con el tipo de datos sin firmar char como "recuento" e inicializamos el recuento con cero. Luego, creamos dos funciones: una para obtener Add y otra para restablecer la búsqueda. Ejecutamos el contador de incremento 1 para agregar y disminución 1 para restar en ambas funciones. Luego, imprimimos estos valores de las funciones Fetch_add y Fetch_Sub en la principal.

La función fetch_add devolvió 0 y 1 como los valores anteriores antes del incremento. Del mismo modo, el fetch_sub regresó 2 y 1 como los valores almacenados previamente antes de la resta o la disminución del uno.

Conclusión

Implementamos las operaciones básicas en "STD :: Atomic" en este artículo. Aprendimos cómo podemos lidiar con los problemas en las aplicaciones de lectura múltiple utilizando el STD Atomic. Implementamos los diversos ejemplos en C ++ para las diferentes funciones como Fetch, Exchange, Reading/Writing y Memory Model del STD Atomic para garantizar la consistencia secuencial y los comportamientos bien definidos del código para aplicaciones múltiples.