Práctica 06 - ProgProcesosYServicios/Practicas-2 GitHub Wiki

Práctica 2.6: Exclusión mutua: el algoritmo de Dekker (cuarto intento)

La solución anterior no funciona porque sufre interbloqueo. El punto delicado en este caso está al inicio del método enSeccion€ritica(int). Si las dos hebras, simultáneamente ponen a cierto sus banderas, luego quedarán indefinidamente esperando a que la otra salga de la sección crítica. En monoprocesador es difícil que el azar genere interbloqueo, pero puedes forzarlo añadiendo un Thread.yield() en la línea 4.

El problema principal se debe a que la semántica de las banderas ahora no es si una hebra ha entrado en la sección crítica, sino si tiene intención de entrar, dado que las estamos activando antes de hacerlo. El interbloqueo se produce porque las dos hebras ven que la otra tiene intención de entrar, asumen que, de hecho, ya ha entrado, y esperan a que salga.

La solución es hacer que las hebras tengan paciencia y anulen, temporalmente, su intención de entrar en la sección crítica si ven que la otra hebra también lo ha hecho. De esa forma se evita el interbloqueo, porque el recurso “se libera”, se espera un instante, y se vuelve a intentar.

Haz una copia del proyecto de la práctica anterior, y renombra la clase a Dekker4.

Modiica el método entradaSeccionCritica(int):

	protected void entradaSeccionCritica(int numHebra) {

		_enSeccionCritica[numHebra].valor = true;

		int otraHebra = numHebra ^ 0x1;
		while(_enSeccionCritica[otraHebra].valor)
                        // Dejamos pasar al otro...
			_enSeccionCritica[numHebra].valor = false;
			// ... esperamos un momento...
			Thread.yield(); 
			// ... y volvemos a intentarlo.
			_enSeccionCritica[numHebra].valor = true;
		}
		
		// ¡Está libre!

	} // entradaSeccionCritica
  • Ejecuta el programa. java p06.Dekker4 ¿Funciona?

  • Ejecutalo en monoprocesador (con taskset en Linux o start /affinity 0x1 en Windows ) ¿Funciona ahora?

  • Dónde está el problema?