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

Práctica 2.7: Exclusión mutua: el algoritmo de Dekker: solución final

La solución de la práctica anterior sufre livelock (“bloqueo vital”) si las dos hebras insisten en ceder el turno a la otra, entrando en un bucle de “cortesía mutua”. Es poco probable que esta amabilidad dure para siempre (porque el planificador no mantendrá “sincronizadas” las dos hebras tanto tiempo), pero aun así no es una alternativa válida.

La solución es mezclar esta última propuesta con la primera en la que llevábamos el turno. Además de tener las dos banderas, llevamos quién tiene el turno para los casos de empate. Si una hebra muestra su intención de entrar en la sección crítica, y al comprobar las intenciones de la otra hebra ve que su bandera también está activa, entonces cambiará momentáneamente de opinión sólo si no es su turno. Si es su turno, entonces asumirá que la otra la dejará pasar a ella, e insistirá en esperar a que desista. De otro modo, desistirá ella, y volverá a probar un momento después.

Haz una copia del proyecto de la práctica anterior, y renombra la clase a DekkerFinal. Modifica el método entradaSeccionCrítica(int):

	protected void entradaSeccionCritica(int numHebra) {

          //Simulamos que estamos dentro
		_enSeccionCritica[numHebra].valor = true;

		int otraHebra = numHebra ^ 0x1;
		while(_enSeccionCritica[otraHebra].valor) {
			if (_turno == otraHebra) {	
				_enSeccionCritica[numHebra].valor = false;
				while(_turno == otraHebra)
				; // Espera activa
				_enSeccionCritica[numHebra].valor = true;
			}
			else {
				;
			}
		} // while
		
		// ¡Está libre!

	} // entradaSeccionCritica
  • Ejecuta el programa y comprueba que funciona.
  • Encuentras algún problema a este algoritmo?