Buscar..


Introducción

Al escribir aplicaciones de subprocesos múltiples, uno de los problemas más comunes que se experimentan son las condiciones de carrera. Así que documentamos el ¿Cómo los detectas? y como los manejas?

Ejemplo: Considerar tendrá dos hilos T1 y T2.

¿Cómo los detectas?

Si varios subprocesos pueden acceder a la misma ubicación de variable / recurso / memoria y al menos uno de ellos está cambiando el valor de ubicación de variable / recurso / memoria , entonces puede ocurrir la Condición de Carrera . Porque si un hilo está cambiando el valor de la ubicación de variable / recurso / memoria y otro hilo intenta leer lo mismo, entonces no obtendrá el valor actualizado.

Nota : si todos los subprocesos solo están leyendo la ubicación de la variable / recurso / memoria, entonces no se producirá la Condición de Carrera .

Ejemplo: Programa sufre de Condición de Carrera

#include <stdio.h>
#include <pthread.h>

int x= 0;

void* fun(void* in)
{
    int i;
    for ( i = 0; i < 10000000; i++ )
    {
        x++;
    }
}

int main()
{
    pthread_t t1, t2;
    printf("Point 1 >> X is: %d\n", x);

    pthread_create(&t1, NULL, fun, NULL);
    pthread_create(&t2, NULL, fun, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    printf("Point 2 >> X is: %d\n", x);
    return 0;
}

La salida en mi pantalla es:

Point 1 >> X is: 0
Point 2 >> X is: 9925047

Su salida puede variar. Pero seguro que no serán 20.000.000. Dado que ambos subprocesos ejecutan el mismo bucle y tienen una variable global int x;

for ( i = 0; i < 10000000; i++ )
{
   x++; 
}

Entonces, el valor final de x en la línea Point 2 >> X is: 9925047 debe ser 20,000,000. Pero no es así.

El estado de x se puede cambiar por otro hilo durante el tiempo entre x se está leyendo y cuando se vuelve a escribir.

Digamos que un hilo recupera el valor de x, pero aún no lo ha almacenado. ¡Otro hilo también puede recuperar el mismo valor de x (porque ningún hilo lo ha cambiado todavía) y luego ambos estarían almacenando el mismo valor (x + 1) de nuevo en x!

Ejemplo:

Hilo 1: lee x, el valor es 7

Hilo 1: agregue 1 a x, el valor ahora es 8

Hilo 2: lee x, el valor es 7

Hilo 1: almacena 8 en x

Hilo 2: agrega 1 a x, el valor ahora es 8

Hilo 2: almacena 8 en x

¿Cómo los manejas?

Las condiciones de carrera pueden evitarse empleando algún tipo de mecanismo de bloqueo antes del código que accede al recurso compartido o la exclusión mutua.

A continuación se modifica el programa:

Ejemplo: problema de condición de carrera resuelto

#include <stdio.h>
#include <pthread.h>

int x= 0;
//Create mutex
pthread_mutex_t test_mutex;

void* fun(void* in)
{
    int i;
    for ( i = 0; i < 10000000; i++ )
    {
        //Lock mutex before going to change variable
        pthread_mutex_lock(&test_mutex);
        x++;
        //Unlock mutex after changing the variable
        pthread_mutex_unlock(&test_mutex);
    }
}

int main()
{
    pthread_t t1, t2;
    printf("Point 1 >> X is: %d\n", x);

    //Initlize mutex
    pthread_mutex_init(&test_mutex, NULL);

    pthread_create(&t1, NULL, fun, NULL);
    pthread_create(&t2, NULL, fun, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    //Destroy mutex after use
    pthread_mutex_destroy(&test_mutex);
    printf("Point 2 >> X is: %d\n", x);
    return 0;
}

A continuación se muestra la salida:

Point 1 >> X is: 0
Point 2 >> X is: 20000000

Aquí, la respuesta sale como 20,000,000 cada vez.

Nota : el programa modificado, que está libre de error de condición de carrera, tardará mucho en ejecutarse. Porque hay sobrecarga en el bloqueo y desbloqueo mutex .



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow