UNIVERSIDAD NACIONAL DE SAN ANTONIO ABAD DEL CUSCO PROGRAMACIÓN CONCURRENTE Y PARALELA Regiones Críticas y Regiones Críticas Condicionales Ing. Ivan Medrano Valencia 1 Indice Problemas con semáforos Definición de las regiones críticas Implementación de las regiones críticas Regiones Críticas condicionales Algunos problemas con Regiones Críticas condicionales 2 Problemas con semáforos Debidos fundamentalmente a errores en la programación, es decir, en la secuencia de las operaciones wait y signal. Intercambio de wait y signal: Cambio de wait y signal: Omisión de wait o signal: signal(mutex); Sección_crítica wait(mutex); wait(mutex); Sección_crítica wait(mutex); //wait(mutex); Sección_crítica //signal(mutex); No exclusión mutua Dificil detección Interbloqueo Interbloqueo No exclusión mutua 3 Definición de las regiones críticas Una región crítica es una pieza de código que, POR DEFINICIÓN, siempre se ejecuta bajo exclusión mutua. Las variables que deben ser protegidas de ser accedidas concurrentemente se agrupan en regiones. Estas variables se etiquetan explícitamente como compartidas. Se prohibe que los procesos entren en una región en la que ya hay otro proceso activo. 4 Definición de las regiones críticas Notación original Brinch Hansen. Dos componentes: Una forma de declarar las variables que deben ser accedidas bajo exclusión mutua var V: compartida T; donde V es el nombre de la variable y T es el tipo. Una nueva estructura que se usa para codificar la operación a realizar sobre la variable region V hacer S donde V es el nombre de la variable a ser accedida en la región crítica y S implementa la acción requerida. Mientras se ejecuta S ningún otro proceso puede acceder a V. 5 Ejemplo Las RCs se pueden anidar, pero debe tenerse en cuenta que las RCs no se deben anidar en orden inverso en los procesos, de lo contrario podría producirse un interbloqueo. 6 REGION CRITICA CONDICIONAL Problemas con las regiones críticas Si se anidan las regiones críticas pueden producirse interbloqueos P: region X do region Y do S1; Q: region Y do region X do S2; P y Q se quedan esperando Las regiones críticas resuelven la exclusión mutua pero no la sincronización en general. Regiones Críticas Condicionales 7 REGION CRITICA DONDICIONAL Con los mecanismos vistos hasta ahora (RCs y semáforos) el hecho de que un proceso que quiere acceder a un objeto compartido deba esperar a que se cumpla una cierta condición (espera condicional) no resulta fácil de implementar, al menos si se pretende que dicha espera sea pasiva. La condición, habitualmente, hará referencia al objeto compartido. 8 RCC Supóngase que un proceso quiere acceder a una variable compartida x pero sólo si se cumple la condición B(x). Una forma simple de implementar la espera condicional pero que implica una espera activa es la siguiente: 9 RCC A principios de los 70 Hoare y Brinch Hansen propusieron un mecanismo de alto nivel que permite realizar la espera condicional de forma pasiva: la región crítica condicional (RCC). Una RCC sólo se diferencia de una RC en que dentro de la RCC existe una sentencia espera_a_que B. Dicha primitiva sólo puede estar dentro de una RC. Si existen varias RCs anidadas, espera_a_que se asocia con la más próxima. Esta sentencia produce una espera pasiva. Su semántica es la siguiente: 1. Si la condición B es cierta el proceso continúa por la siguiente sentencia a la espera_a_que. 2. Si la condición B es falsa el proceso detiene su ejecución, abandona la RC para permitir a otros procesos entrar en ella y pasa a una cola Qs de espera asociada con la RC. 10 RCC • Qv que es donde espera un proceso cuando quiere entrar a una RC que está ocupada. Constituye la cola de entrada a la RC. • Qs que es donde esperan los procesos que evaluaron la condición de la sentencia espera_a_que a falso. 11 IMPLEMENTACION DE RCC CON SEMAFOROS Inicio {de ka RCC} wait(v) {ejecuta el equivalente del espera_a_que hasta que se cumpla B(x)} mientras no B(x) hacer Inicio suspendidos_s = suspendidos_s + 1 {inicialmente 0} signal(v) {salida momentánea de la RCC} wait(s) wait(v) {intento de reentrada a la RCC (espera sobre Qv)} fins {en este punto un proceso ha completado la RCC por lo que deben pasarse los procesos suspendidos sobre la cola Qs a la cola Qv} mientras (suspendidos_s > 0) hacer Inicio suspendidos_s = suspendidos_s - 1 signal(s) fins signal(v) Fin {de la RCC} 12 Problema: Productor-Consumidor (1) procedure SacarDeBuffer(var ch: char); begin ch := Buffer.Items[Buffer.ProxSal]; Buffer.ProxSal := Buffer.ProxSal mod TamañoBuffer; Buffer.Cuantos := Buffer.Cuantos -1; end; program pcRCC; const TamañoBuffer = 5; type TipoBuffer = record Items: array[1..TamañoBuffer] of char; ProxEnt: integer; (*código del productor ProxSal: integer; Cuantos: integer; end; begin var (*inicializar Buffer*) Buffer : shared TipoBuffer; cobegin Productor; Consumidor; coend; procedure PonerEnBuffer(ch: char); end; begin Buffer.Items[Buffer.ProxEnt] := ch; Buffer.ProxEnt := Buffer.ProxEnt mod TamañoBuffer; Buffer.Cuantos := Buffer.Cuantos +1; end; y consumidor*) 13 Problema: Productor-Consumidor (2) process Productor; var item : char; begin for item := ‘a’ to ‘z’ do region Buffer when Buffer.Cuantos < TamañoBuffer do PonerEnBuffer(item); end; process Consumidor; var local : char; begin repeat region Buffer when Buffer.Cuantos <> 0 do SacarDeBuffer(local); write(local); until local = ‘z’; writeln end; 14 Problema: Lectores-Escritores (1) Precedencia a Lectores var v: shared record Lectores,Escritores : integer end; process Lector (ident: integer); begin region v do Lectores := Lectores +1; region v when Escritores = 0 do; Leer; region v do Lectores := Lectores – 1; end; process Escritor (ident: integer); begin region v when Lectores = 0 do Escritores := Escritores +1; region v do begin Escribir; Escritores := Escritores – 1; end; end; 15 Problema: Lectores-Escritores (2) Precedencia a Escritores var v: shared record Lectores,Escritores : integer end; process Lector (ident: integer); begin region v when Escritores = 0 do Lectores := Lectores +1; Leer; region v do Lectores := Lectores – 1; end; process Escritor (ident: integer); begin region v do Escritores := Escritores +1; region v when Lectores = 0 do begin Escribir; Escritores := Escritores – 1; end; end; 16 Problema: Filosofos de cena var v: shared T; palillos: array [0..N-1] of boolean; process type filosofos(nom: integer); begin repeat sleep(random(5)); (*Pensando*) region v when palillos[nom] do palillos[nom] := false; region v when palillos[(nom mod N) + 1] do palillos[(nom mod N) + 1] := false; sleep(random(5)); (*Cenando*) region v do begin palillos[nom] := true; palillos[(nom mod N) + 1] := true; end; forever end; 17 Evaluación de las RCC Limitaciones Pueden estar dispersas en el texto del programa La integridad de una estructura de datos compartida es facilmente dañada Dificiles de implementar eficientemente 18