pthreads
Condición de carrera en pthreads.
Buscar..
Introducción
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 .