Cuando se escriben aplicaciones multihilo, uno de los problemas más comunes son las condiciones de carrera.
Mis preguntas a la comunidad son:
¿Qué es una condición de carrera? ¿Cómo se detectan? ¿Cómo se manejan? Por último, ¿cómo se evita que se produzcan?
Una condición de carrera ocurre cuando dos o más hilos pueden acceder a los datos compartidos y tratan de cambiarlos al mismo tiempo. Dado que el algoritmo de programación de hilos puede intercambiar entre ellos en cualquier momento, no se sabe el orden en que los hilos intentarán acceder a los datos compartidos. Por lo tanto, el resultado del cambio de datos depende del algoritmo de programación de hilos, es decir, ambos hilos están "compitiendo" para acceder/cambiar los datos.
Los problemas suelen producirse cuando un hilo hace una "comprobación-entonces-acción" (por ejemplo, "comprobar" si el valor es X, y luego "actuar" para hacer algo que depende de que el valor sea X) y otro hilo hace algo al valor entre la "comprobación" y la "acción". Por ejemplo
if (x == 5) // The "Check"
{
y = x * 2; // The "Act"
// If another thread changed x in between "if (x == 5)" and "y = x * 2" above,
// y will not be equal to 10.
}
El punto es, y podría ser 10, o podría ser cualquier cosa, dependiendo de si otro hilo cambiado x en entre la comprobación y el acto. No tienes forma de saberlo.
Para evitar que se produzcan condiciones de carrera, se suele poner un bloqueo alrededor de los datos compartidos para asegurar que sólo un hilo puede acceder a los datos a la vez. Esto significaría algo así:
// Obtain lock for x
if (x == 5)
{
y = x * 2; // Now, nothing can change x until the lock is released.
// Therefore y = 10
}
// release lock for x
Una condición de carrera es un tipo de error que se produce sólo con ciertas condiciones temporales.
Ejemplo: Imagina que tienes dos hilos, A y B.
En el hilo A
<language: c -->
if( object.a != 0 )
object.avg = total / object.a
En el hilo B:
object.a = 0
Si el hilo A se adelanta justo después de haber comprobado que el objeto.a no es nulo, B hará a = 0
, y cuando el hilo A gane el procesador, hará una "división por cero".
Este error sólo ocurre cuando el hilo A es adelantado justo después de la sentencia if, es muy raro, pero puede ocurrir.
Una condición de carrera es una situación en la programación concurrente en la que dos hilos o procesos concurrentes compiten por un recurso y el estado final resultante depende de quién obtiene el recurso primero.