20/01/2015 Exclusión Mutua Dr. Víctor J. Sosa [email protected] Problema de Exclusión Mutua • Cuando accedemos a datos compartidos es importante sincronizar el acceso para que los datos no se pierdan. • Las operaciones de actualización de información actuales no son atómicas: x = x +1. LD R, x ; carga x al registro R INC R; incrementa el registro R ST R, x; almacena el registro R en x 1 20/01/2015 Ejemplo de una Interfaz Java mínima para exclusión mutua Public interface Lock { public void accederSC(int pid); public void liberarSC(int pid); } Algoritmo de Peterson Class Intento1 implements Lock { boolean puertaAbierta = true; Ejemplo de una propuesta para manejar dos procesos intentando utilizar una sección crítica (SC) public void accederSC(int i) { while (!puertaAbierta) ; // Esta ocupado puertaAbierta = false; } public void liberarSC(int i) { puertaAbierta = true; } } ¿cómo se quién cambio primero la variable puertaAbierta? Problema: No garantiza la exclusión mutua! 2 20/01/2015 Algoritmo de Peterson Class Intento2 implements Lock { boolean quieroSC[] = {false, false}; Ejemplo de una propuesta para manejar dos procesos intentando utilizar una sección crítica (SC) public void accederSC(int i) { quieroSC[i] = true; // manifiesto mi intencion de entrar while (quieroSC[1- i]) ; // Esta ocupado } public void liberarSC(int i) { quieroSC[i] = false; } } ¿y si ambos manifiestan su intención de entrar? Problema: Deadlock!! Algoritmo de Peterson Class Intento3 implements Lock { int turno = 0; Ejemplo de una propuesta para manejar dos procesos intentando utilizar una sección crítica (SC) public void accederSC(int i) { while (turno == 1 - i) ; // Esta ocupado } public void liberarSC(int i) { turno = 1 - i; } } Igualdad de oportunidades, a cada quien se le sede un turno ala vez. Exclusion Mutua Deadlock Hambruna ☺ ☺ 3 20/01/2015 Algoritmo de Peterson* Class AlgoritmoPeterson implements Lock { boolean quieroSC[] = {false, false}; int turno = 1; public void accederSC(int i) { int j = 1 – i; quieroSC[i] = true; // manifiesto mi intencion de entrar turno = j; while (quieroSC[j] && (turno == j)) ; // Esta ocupado } public void liberarSC(int i) { quieroSC[i] = false; } } *G. L. Peterson, Myths about the mutual exclusion problem. Information Processing Letters, vol. 12, no. 3, pp. 115-116, Junio 1981. public class MyThread2_SinLock extends Thread { int myId; Lock lock; static int Total=0; // Seccion Crítica!!! public MyThread2_SinLock(int id, Lock lock) { myId = id; this.lock = lock; } Ejemplo de un programa en Java que podría utilizar un algoritmo de exclusión mutua. Se puede implementar la interface Lock definida al inicio de esta presentación. Por ejemplo implementarla con el algoritmo de Peterson descrito antes . void nonCriticalSection() { System.out.println(myId + " SALIO de la seccion critica\n"); } void CriticalSection() { System.out.println(myId + " ESTA en la seccion critica"); } public void run() { lock.requestCS(myId); CriticalSection(); lock.releaseCS(myId); nonCriticalSection(); } public static void main (String[] args) throws Exception { MyThread2_SinLock t[]; int N = Integer.parseInt(args[0]); t=new MyThread2_SinLock[N]; Lock lock = new Peterson(N); // o algun otro algoritmo de mutex // Lock lock = new Bakery(N); for (int i=0; i<N; i++) { t[i] = new MyThread2_SinLock(i, lock); t[i].start(); } } } 4 20/01/2015 class Bakery implements Lock { int N; boolean [] choosing; // inside doorway int [] number; public Bakery (int numProc) { N=numProc; choosing = new boolean[N]; number = new int[N]; for (int j = 0; j <N; j++) { choosing[j] = false; number[j]=0; } } public void requestCS(int i) { // paso 1: elegir un numero de atencion // tomamos el ultimo numero disponible choosing[i] = true; for (int j=0; j<N; j++) if (number[j] > number[i]) number[i] = number[j]; number[i]++; choosing[i] = false; // paso 2: verificar si mi numero es el menor de todos for(int j=0; j<N; j++) { while (choosing[j]) ; // proceso j intentando tomar un numero //Esta ocupado esperar.. while ( (number[j] !=0) && ( (number[j] < number[i]) || ((number[j] == number[i]) && j<i) ) ) ; } } public void releaseCS (int i) { number[i] = 0; } } 5