TEMA 2. Comunicación y sincronización con memoria compartida Ingeniería en Informática Contenidos El problema de la sección crítica Semáforos Regiones críticas Monitores © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 2 Bibliografía Programación Concurrente Principles of Concurrent and Distributed Programming J. Palma, C. Garrido, F. Sánchez, A. Quesada, 2003 M. Ben-Ari. Prentice Hall, 1990 Capítulo 3 Sistemas Operativos A. Silberschatz, P. Galvin. Addison-Wesley, 1999 Capítulo 6 © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 3 Contenidos El problema de la sección crítica Semáforos Regiones críticas Monitores © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 4 Modelo del sistema Conjunto de procesos cooperativos que se ejecutan de manera asíncrona y que comparten datos Proceso cooperativo: proceso que puede afectar o verse afectado por los demás procesos que se ejecutan en el sistema © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 5 Ejemplo: buffer limitado Productor N: constant integer:=...; type elemento is ...; buffer: array(0..N-1) of elemento; entra,sale: mod N:=0; contador: integer range 0..N:=0; loop ... producir un elemento elem ... loop exit when contador<N; end loop; buffer(entra):=elem; entra:=entra+1; contador:=contador+1; end loop; Consumidor loop loop exit when contador>0; end loop; elem:=buffer(sale); sale:=sale+1; contador:=contador-1; ... consumir elemento elem ... end loop; © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 6 Problema Ambas rutinas son correctas si se ejecutan por separado pero podrían NO funcionar si se ejecutan de manera concurrente Supongamos que contador contiene en un momento dado el valor 5 y que las instrucciones “contador=contador+1” y “contador=contador-1” se ejecutan de forma concurrente (¡contador podría ser 4, 5 o 6!) contador = contador + 1 registro1 := contador; registro1 := registro1 +1; contador : registro1; T0: productor T1: productor T2: consumidor T3: consumidor T4: productor T5: consumidor contador=contador-1 registro2 := contador; registro2 := registro2 -1; contador := registro2; registro1 := contador registro1 := registro1+1 registro2 := contador registro2 := registro2 -1 contador := registro1 contador := registro2 © José Miguel Santos Espino – Alexis Quesada Arencibia (registro1= 5) (registro1 = 6) (registro2 = 5) (registro2 = 4) (contador = 6) (contador = 4) ProgramaciónConcurrente 7 Modelo del sistema N procesos intentan acceder a un recurso compartido en un bucle infinito: loop Sección_No_Crítica; Pre_Protocolo; Sección_Crítica; Post_Protocolo; end loop; Nunca puede haber más de un proceso en la sección crítica (exclusión mutua) Los pre y post protocolos serán algoritmos para garantizar que se cumple la exclusión mutua © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 8 Requisitos de la solución, según Ben-Ari Siempre se debe cumplir la exclusión mutua. Un proceso puede detenerse en su sección no crítica, sin que afecte a los demás procesos. No pueden aparecer interbloqueos. No puede haber inanición: si un proceso declara entrar en s.c., terminará entrando. Progreso si no hay contención: si un solo proceso quiere entrar en s.c., debe poder entrar sin más. © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 9 Requisitos de la solución, según Peterson Exclusión mutua Progreso: si ningún proceso está en sección crítica y hay procesos que desean entrar en su s.c., sólo estos últimos participarán en la decisión y ésta se tomará en un tiempo finito. Espera limitada: hay un límite para el número de veces que otros procesos pueden adelantarse a un proceso que quiere entrar en s.c. © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 10 Primer intento: variable turno turno: integer range 1..2 := 1; loop SNC1; loop exit when turno=1; end loop; SC1; turno:=2; end loop; © José Miguel Santos Espino – Alexis Quesada Arencibia loop SNC2; loop exit when turno=2; end loop; SC1; turno:=1; end loop; ProgramaciónConcurrente 11 Discusión del primer intento ¿Garantiza exclusión mutua? ¿Está libre de interbloqueo? ¿Está libre de inanición? ¿Garantiza el progreso si no hay contención? © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 12 Segundo intento: avisadores flag1,flag2: boolean := true; loop SNC1; loop exit when flag2; end loop; flag1:=false; SC1; flag1:=true; end loop; loop SNC2; loop exit when flag1; end loop; flag2:=false; SC2; flag2:=true; end loop; © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 13 Tercer intento flag1,flag2: boolean := true; loop SNC1; flag1:=false; loop exit when flag2; end loop; SC1; flag1:=true; end loop; loop SNC2; flag2:=false; loop exit when flag1; end loop; SC2; flag2:=true; end loop; © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 14 Solución de Peterson flag1,flag2: boolean := true; turno: integer range 1..2 := 1; loop SNC1; flag1:=false; turno:= 2; loop exit when flag2 or turno=1; end loop; SC1; flag1:=true; end loop; © José Miguel Santos Espino – Alexis Quesada Arencibia loop SNC2; flag2:=false; turno:= 1; loop exit when flag1 or turno=2; end loop; SC2; flag2:=true; end loop; ProgramaciónConcurrente 15 Soluciones hardware Entorno uniprocesador: prohibir las interrupciones mientras se modifican variables compartidas Problema: Entorno multiprocesador Instrucciones atómicas test-and-set o SWAP. © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 16 Soluciones hardware Permiten evaluar y asignar un valor a una variable de forma atómica. test-and-set(B): Pone B a true y devuelve el antiguo valor de B. SWAP(A,B): Intercambia los valores de A y B. Si disponemos de estas instrucciones, se simplifica muchísimo el problema de la sección crítica. © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 17 Soluciones al problema de la SC con instrucciones HD atómicas loop SNC1; loop exit when Test_and_Set(llave)=false; end loop; SC1; llave:=false; end loop; loop SNC1; llave:=true; loop Swap(cerradura,llave); exit when llave=false; end loop; SC1; cerradura:=false; end loop; © José Miguel Santos Espino – Alexis Quesada Arencibia ProgramaciónConcurrente 18