La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

1 Concurrencia: Exclusión mutua y Sincronización.

Presentaciones similares


Presentación del tema: "1 Concurrencia: Exclusión mutua y Sincronización."— Transcripción de la presentación:

1 1 Concurrencia: Exclusión mutua y Sincronización

2 2/111 Concurrencia: Exclusión mutua y Sincronización Principios de la concurrencia. Exclusión mutua y sincronización:  Soluciones de Software,  Soporte del hardware,  Semáforos,  Monitores

3 3/111 Concurrencia: Exclusión mutua y Sincronización La concurrencia puede presentarse en tres categorías diferentes  Varias aplicaciones (multiprogramación)  Aplicaciones estructuradas: Algunas aplicaciones pueden implementarse eficazmente como un conjunto de procesos concurrentes  Estructura del OS: Algunos OS están implementados como un conjunto de procesos

4 4/111 Principios Generales de Concurrencia En sistema multiprogramado monoprocesador, los procesos se intercalan en el tiempo para dar apariencia de ejecución simultánea. En un sistema multiprocesador no sólo es posible intercalar, sino también superponer  Procesos (o hilos) concurrentes a menudo necesitan compartir datos (mantenidos en memoria compartida o archivos) y recursos.

5 5/111 Principios Generales de Concurrencia En sistema multiprogramado monoprocesador  Si no hay acceso controlado a los datos compartidos, algunos procesos obtendrán una visión inconsistente de estos datos.  La acción realizada por la ejecución concurrente de procesos, dependerá entonces del orden en el cual su ejecución es entrelazada

6 6/111 Problemas con la ejecución concurrente Los problemas creados por la multiprogramación parten de que la velocidad relativa de los procesos no puede predecirse. Depende de la actividad de otros procesos, de la forma en que el SO trata las interrupciones y de la políticas de planificación. Los problemas creados con los sistemas multiprocesados, son iguales a los anteriores. Además, se originan problemas por tener varios procesos en ejecución paralelamente.

7 7/111 Dificultades de la ejecución concurrente La compartición de recursos globales, está llena de riesgos (el orden en el cual se ejecutan lecturas y escrituras, es crítico) Para el OS resulta difícil asignar recursos de forma óptima Resulta difícil localizar un error de programación, por cuanto los resultados no son normalmente reproducibles.

8 8/111 Comunicación entre Procesos Los procesos cooperantes necesitan mecanismos para sincronizarse y comunicarse información de forma segura Sincronización  Ordenación temporal de la ejecución de procesos A antes que B Tortilla de patatas BatirPelarPelar HuevosCebollas Papas Mezclar, Añadir Sal y Freír Comunicación  Paso de información entre tareas Síncrona o Asíncrona Filtros ó Pipes en Unix: who | wc | sed -e ‘s/ [ ]*/:/g’ | cut -d: -f2 Canal de Panamá

9 9/111 Interacción entre procesos (Procesos en Competición) Los procesos no tienen conocimiento de los demás  Relación: Competencia  Influencia de un proceso en los otros Los resultados de un proceso son independientes de las acciones de los otros Los tiempos de los procesos pueden verse afectados  Posibles problemas de control Exclusión mutua Interbloqueo Inanición

10 10/111 Interacción entre procesos Los procesos tienen conocimiento indirecto de los otros (objetos compartidos)  Relación: Cooperación por compartición  Influencia de un proceso en los otros Los resultados de un proceso pueden depender de la información obtenida de los otros Los tiempos de los procesos pueden verse afectados  Posibles problemas de control Exclusión mutua Interbloqueo Inanición Coherencia de datos

11 11/111 Interacción entre procesos Los procesos tienen conocimiento directo de los otros (hay disponibles primitivas de comunicación)  Relación: Cooperación por comunicación  Influencia de un proceso en los otros Los resultados de un proceso pueden depender de la información obtenida de los otros Los tiempos de los procesos pueden verse afectados  Posibles problemas de control Interbloqueo Inanición

12 12/111 Condiciones de Carrera ó Competencia La falta de sincronismo entre procesos da problemas Canal de Panamá  Barco encallado Tortilla de Patatas  No hay quien se la coma Uso de datos / recursos comunes  Inconsistencia ¡Que buen negocio! ¡Me tumban!

13 13/111 Condiciones de Carrera program taxistas; const numTaxistas = 2; var cuenta : integer; process type taxista (t: integer); var taxista1, taxista2: taxista; begin cuenta := 0; cobegin taxista1(1); taxista2(2); coend; writeln (‘Total recaudacion =‘,cuenta: 7) end. Ingreso de Taxista 1 = 27439 Ingreso de Taxista 2 = 27092 Total recaudación = 47055 + 54531

14 14/111 Ingreso Condiciones de Carrera Buscar Cliente Hacer Carrera process type taxista (t: integer); (* constantes y variables *) begin recaudacion := 0; mio := 0; repeat for i:=1 to random (maxEspera) do null; importe := random (maxImporte); mio := mio + (importe div ratioTaxista); cuenta := cuenta + importe – (importe div ratioTaxista); recaudacion := recaudacion + importe until mio >= sueldoDia; writeln (‘Ingreso de Taxista’, t:2, ‘ =‘, recaudacion – mio); end;

15 15/111 Condiciones de Carrera (El problema) 3: cuenta := cuenta + importe 3.1: PUSH importe 3.2: PUSH cuenta 3.3: ADDP 3.4: POP cuenta 3.1, 3.2 T1T1 T2T2 5.000 cuenta 10.000 T1.importe 3.3 5.000 10.000 T1.SP 3.1, 3.2 1.500 T2.importe 3.3 5.000 1.500 T2.SP 3.3, 3.4 15.000 cuenta 3.3, 3.4 6.500 cuenta 6.500 ¿problema?

16 16/111 Exclusión mutua y Región crítica (La solución) RC Aquí como máximo un Pi Exclusión Mutua Integridad Datos Comunes Aquí cero, uno o más Pi Los Pi indicarán cuándo EntranEnRC y cuándo SalenDeRC

17 17/111 Exclusión mutua y Región crítica (La solución) EntrarEnRC; cuenta := cuenta + importe – (importe div ratioTaxista); SalirDeRC; REQUISITOS En una misma Región Crítica no más de un proceso Sin supuestos: #µP, #Pi, velocidades relativas,..... Ningún Pi fuera de su Región Crítica bloqueará a otros Pj Decisión de quién entra a una Región Crítica en un tiempo finito

18 18/111 El problema de la sección crítica Cuando un proceso ejecuta código que manipula datos compartidos (o recursos), se dice que el proceso está en su sección crítica (CS) (para esos datos compartidos) La ejecución de secciones críticas debe ser mutuamente excluyente: en cualquier momento, sólo a un proceso se le permite ejecutar en su sección crítica (incluso con múltiples CPUs ) Entonces cada proceso debe requerir el permiso para entrar en su sección crítica (CS)

19 19/111 El problema de la sección crítica La sección de código que lleva a cabo este requerimiento se llama la sección de entrada La sección crítica (CS) podría ser seguida por una sección de salida El código restante es el resto de la sección El problema de la sección crítica es diseñar un protocolo que los procesos puedan usar, para que su acción no dependa del orden en el cual su ejecución es entrelazada (posiblemente en muchos procesadores)

20 20/111 Esquema para el análisis de soluciones Cada proceso se ejecuta a una velocidad diferente de cero, pero no se puede asumir nada con respecto a la velocidad relativa de n procesos Estructura general de un proceso: Muchos CPUs pueden estar presente pero el hardware de memoria previene el acceso simultáneo a la misma localización de memoria No se puede asumir nada sobre el orden de ejecución entrelazada Para las soluciones: se necesita especificar secciones de entrada y de salida repeat entry section critical section exit section remainder section forever

21 21/111 Esquema para el análisis de soluciones

22 22/111 Requisitos para una solución válida al problema de la sección crítica Exclusión mutua  Sólo un proceso, de entre todos los que poseen secciones críticas por el mismo recurso u objeto compartido, debe tener permiso para entrar en ella en un instante dado Progreso  Si ningún proceso se está ejecutando en su CS mientras algunos procesos desean entrar, sólo los procesos que no están en su CS pueden participar en la decisión de cual es el próximo en entrar en su CS. Esta selección no puede posponerse indefinidamente

23 23/111 Requisitos para una solución válida al problema de sección la crítica Espera limitada  Después que un proceso ha hecho un requerimiento para entrar en su CS, hay un límite en el número de veces en el que a los otros procesos se les permite entrar en su CS De lo contrario el proceso padecerá inanición

24 24/111 Atomicidad Se supone que las instrucciones básicas de lenguaje máquina tales como “Load”, “store” y “test”, se ejecutan de forma atómica.  Es decir: Si dos de tales instrucciones se ejecutan de manera concurrente, el resultado es equivalente a su ejecución secuencial en algún orden desconocido.

25 25/111 Tipos de soluciones Soluciones de software  Algoritmos cuya correctitud no confían en asumir ninguna característica de hardware Soluciones de hardware  Se cuenta con algunas instrucciones de máquina especiales Soluciones del Sistema Operativo  El SO proporciona algunas funciones y estructura de datos al programador

26 26/111 Soluciones de software Primero se considera el caso de 2 procesos  Algoritmos 1 y 2 son incorrectos (algoritmo de Decker)  Algoritmo 3 es correcto (algoritmo de Peterson) Notación  Se comienza con 2 procesos: P0 y P1  Al presentar el proceso PI, PJ siempre denota el otro proceso (I !=J)

27 27/111 Algoritmo 1 La variable compartida turn, es inicializada (a 0 o 1) antes de ejecutar cualquier Pi La sección crítica de Pi es ejecutada si y sólo si turn = i Process Pi: repeat while(turn!=i){}; CS turn:=j; RS forever

28 28/111 Algoritmo 1. Explicación Exclusión mutua  Pi está ocupado esperando si Pj está en su CS: la exclusión mutua es satisfecha Progreso  El requerimiento de progreso no es satisfecho debido a que se presenta una estricta alternación de CSs. Espera Limitada  Por la misma razón anterior, se cumple la espera limitada

29 29/111 Algoritmo 1 Explicación: P0 tiene un RS largo y P1 tiene un RS pequeño. Si turn=0, P0 entra en su CS y luego en su Largo RS (turn=1). P1 entra en su CS y luego en su RS (turn=0) y trata de nuevo de entrar en su CS: Requerimiento rechazado. Este tiene que esperar que P0 deje su RS. Process Pi: repeat while(turn!=i){}; CS turn:=j; RS forever

30 30/111 Algoritmo 2 Mantenga 1 variable Booleana por cada proceso: flag[0] y flag[1] Pi indica que está listo para entrar en su CS mediante: flag[i]:=true La Exclusión mutua está satisfecha pero no el requerimiento de progreso Si se tiene la secuencia:  T0: flag[0]:=true  T1: flag[1]:=true Ambos procesos esperaran entrar en su CS por siempre: se tiene un deadlock (bloqueo) Process Pi: repeat flag[i]:=true; while(flag[j]){}; CS flag[i]:=false; RS forever

31 31/111 Algoritmo 3 (algoritmo de Peterson) Inicialización: flag[0]:=flag[1]:=false turn := 0 o 1 La voluntad de entrar en CS es especificada por flag[i]:=true Si ambos procesos intentan entrar en su CS simultáneamente, solamente un valor de turn se mantendrá Sección de finalización: especifica que Pi está reacio a entrar en su CS Process Pi: repeat flag[i]:=true; turn:=j; do {} while (flag[j]and turn=j); CS flag[i]:=false; RS forever

32 32/111 Algoritmo 3: prueba de correctitud La exclusión mutua es preservada desde que:  Ambos, P0 y P1 están en CS solamente si flag[0] = flag[1] = true y sólo si turn = i para cada Pi (posible) Queda demostrado que el progreso y los requisitos de espera limitada están satisfechos:  Pi no puede entrar en CS solo si entra en el while() con la condición flag [j] = true y su turn = j.  Si Pj no está listo entrar en CS entonces flag [j] = false y Pi puede entrar en su CS

33 33/111 Algoritmo 3: prueba de correctitud  Si Pj ha puesto flag [j]=true y está en su while(), entonces turn=i o turn=j  Si el turn=i, entonces la Pi entra en CS. Si turn=j entonces Pj entra en CS pero restablecerá flag[j]=false en la salida: permitiendo a Pi entrar en CS  Pero si Pj tiene tiempo para restablecer flag[j]=true, también debe poner turn=i  Desde que Pi no cambia el valor de turn mientras está en el while(), Pi entrará en CS después de a lo sumo una entrada en CS por Pj (espera limitada)

34 34/111 ¿Qué hay sobre las fallas de un proceso? Si los tres (3) criterios (ME, progreso, espera limitada) son satisfechos, entonces una solución válida proporcionará robustez contra fallas de un proceso en su remainder section (RS)  Esto es debido a que tener fallas en el RS es como tener un RS infinitamente largo Sin embargo, ninguna solución válida puede proporcionar robustez contra un proceso que falla en su sección crítica (CS)  Una proceso Pi que falla en su CS no señala ese hecho a los otros procesos: para ellos Pi está todavía en su CS

35 35/111 Solución de n procesos: algoritmo de la panadería Antes de entrar en su CS, cada Pi recibe un número. El poseedor del número más pequeño entra en CS (igual que en panaderías, heladerias...) Cuando Pi y Pj reciben el mismo número:  si i <j entonces Pi se sirve primero, en caso contrario Pj se sirve primero Pi restablece su número a 0 en la sección de salida Notación:  (a,b) <(c,d) si a < c o si a = c y b <d  max(a0,...ak) es un número b tal que b >= ai para i=0,..k

36 36/111 El algoritmo de la panadería (cont.) Datos compartidos:  Escogiendo: array[0..n-1] de boolean; Inicializado a falso  Número: array[0..n-1] de entero; Inicializado a 0 La correctitud confía en el hecho siguiente:  Si Pi está en CS y Pk ya ha escogido su number[k] != 0, entonces (number[i],i) <(number[k],k)  Pero la prueba es algo truculenta...

37 37/111 El algoritmo de la panadería (cont.) Process Pi: repeat choosing[i]:=true; number[i]:=max(number[0]..number[n-1])+1; choosing[i]:=false; for j:=0 to n-1 do { while (choosing[j]) {}; while (number[j]!=0 and (number[j],j)<(number[i],i)){}; } CS number[i]:=0; RS forever

38 38/111 Inconvenientes de soluciones del software Procesos que están pidiendo entrar en su sección crítica están en espera ocupada (consumiendo tiempo del procesador inútilmente) Si CSs son largas, sería más eficaz bloquear procesos que están esperando...

39 39/111 Soluciones del hardware: desactivar interrupciónes En un monoprocesador: la exclusión mutua es preservada pero la eficacia de ejecución se degrada: mientras un proceso este en su CS, no se puede entrelazar la ejecución con otros procesos que están en su RS En un multiprocesador: la exclusión mutua no es preservada Generalmente es una solución no aceptable Process Pi: repeat disable interrupts critical section enable interrupts remainder section forever

40 40/111 Soluciones de hardware: instrucciones especiales de máquina Normalmente, accesar a una localización de memoria excluye otro acceso simultáneo a esa misma localización Extensión: los diseñadores han propuesto instrucciones de máquina que ejecuten 2 acciones atómicas (indivisibles) en la misma localización de memoria ( leyendo y escribiendo)

41 41/111 Soluciones de hardware: instrucciones especiales de máquina La ejecución de tal instrucción es mutuamente excluyente (incluso con múltiples CPUs) Ellas pueden ser usadas simplemente para proveer exclusión mutua, pero se necesita algoritmos más complejos para satisfacer los 3 requerimientos del problema de la Sección Critica (CS)

42 42/111 La instrucción test-and-set Una descripción C++ de test-and-set: Un algoritmo que usa testset para la Exclusión Mutua La variable compartida b es inicializada a 0 Sólo el primer Pi que cambia (set) b entra en CS bool testset(int& i) { if (i==0) { i=1; return true; } else { return false; } Process Pi: repeat repeat{} until testset(b); CS b:=0; RS forever

43 43/111 La instrucción test-and-set (cont.) La exclusión mutua es preservada: si Pi entra en CS, los otros Pj están en espera ocupada Problema: aún se usa espera ocupada Cuando Pi sale de su CS, la selección del Pj que entrará en CS es arbitraria: no existe espera limitada. Aquí es posible la inanición

44 44/111 La instrucción test-and-set (cont.) Procesadores (ejem: Pentium) a menudo proveen una instrucción xchg(a,b) atómica, la cual intercambia el contenido de a y b. Pero xchg(a,b) sufre de los mismos inconvenientes que test-and-set

45 45/111 Usando Xchg para la exclusión mutua La variable compartida b se inicializa en 0 Cada Pi tiene una variable local k El único Pi que puede entrar en su CS es el que encuentra b=0 Este Pi excluye todos los otros Pj poniendo b en 1 Process Pi: repeat k:=1 repeat xchg(k,b) until k=0; CS b:=0; RS forever

46 46/111 Problema de las soluciones de Hardware No se pueden generalizar fácilmente a problemas muy complejos!!!!

47 47/111 Semáforos Herramienta de sincronización (proporcionada por el OS), la cual no requiere espera ocupada Un semáforo S es una variable entera que, aparte de la inicialización, sólo puede accederse a través de 2 operaciones atómicas y mutuamente exclusivas:  wait(S)  signal(S) Para evitar espera ocupada: cuando un proceso tiene que esperar, se pondrá en una cola bloqueada de procesos que esperan por el mismo evento

48 48/111 Semáforos Ahora, de hecho, un semáforo es un registro (estructura): type semaphore = record count: integer; queue: list of process end; var S: semaphore; Cuando un proceso debe esperar por un semáforo S, se bloquea y se pone en la cola del semáforo. La operación signal quita (con una política justa como FIFO) un proceso de la cola y lo pone en la lista de procesos listos.

49 49/111 Las operaciones sobre un semáforo (atómicas) wait(S): S.count--; if (S.count<0) { block this process place this process in S.queue } signal(S): S.count++; if (S.count<=0) { remove a process P from S.queue place this process P on ready list } S.count debe ser inicializado a un valor no negativo (dependiendo de la aplicación)

50 50/111 Semáforos: observaciones Cuando S.count >=0: el número de procesos que pueden ejecutar wait(S) sin bloquearse = S.count Cuando S.count <0: el número de procesos esperando en S es = |S.count | Atomicidad y la exclusión mutua: dos (2) procesos no puede estar en wait(S) y signal(S) (en el mismo S) al mismo tiempo (incluso con multiples CPUs) Desde que los bloques de código que definen wait(S) y signal(S) son, en realidad, secciones críticas

51 51/111 Semáforos: observaciones Las secciones críticas definidas por wait(S) y signal(S) son muy cortas: típicamente 10 instrucciones Soluciones:  Uniprocesador: desactiva interrupciones durante esas operaciones (para un periodo muy corto). Esto no trabaja en una máquina multiprocesadora  Multiprocesador: usa software anterior o esquemas de hardware. La cantidad de espera ocupada debe ser pequeña.

52 52/111 Semáforos: observaciones Un semáforo tipo contador: su valor puede variar en un dominio no restringido. Con frecuencia utilizado para controlar el acceso a un determinado recurso formado por un número finito de instancias. Un semáforo binario: sólo puede ser 1 o 0. También se conocen como mutex. Utilizados para proporcionar exclusión mutua.

53 53/111 Usando semáforos por resolver problemas de sección crítica Para n procesos Inicialice S.count en 1 Entonces sólo 1 proceso se permite en CS (exclusión mutua) Para permitir k procesos en CS, se inicializa S.count en k Process Pi: repeat wait(S); CS signal(S); RS forever

54 54/111 Uso de semáforos para sincronizar procesos Se tienen 2 procesos: P1 y P2 Instrucción S1 en P1 necesita ser ejecutada antes de la instrucción S2 en P2 Luego se define un semáforo “synch” Inicialice synch en 0 La sincronización apropiada es lograda teniendo en P1: S1; signal(synch); Y teniendo en P2: wait(synch); S2;

55 55/111 El problema del productor/consumidor Un proceso productor produce información que es consumida por un proceso consumidor  Ejem1: un programa de impresión produce caracteres que son consumidos por una impresora  Ejem2: un ensamblador produce módulos objeto que son consumidos por un cargador Se necesita un buffer para mantener items que son producidos y eventualmente consumidos Un paradigma común para procesos cooperativos

56 56/111 P/C: buffer ilimitado Primero se asume un buffer ilimitado consistiendo de una arreglo de elementos lineal in apunta al próximo item en ser producido out apunta al próximo item en ser consumido

57 57/111 P/C: buffer ilimitado Se necesita un semáforo S para ejecutar exclusión mutua en el buffer: sólo 1 proceso en un momento puede accesar el buffer Se necesita otro semáforo N para sincronizar productor y consumidor en el número N (= in - out) de items en el buffer  Un item puede ser consumido solamente después de que este ha sido creado

58 58/111 P/C: buffer ilimitado El productor es libre de agregar un item en el buffer en cualquier momento: este ejecuta wait(S) antes de añadir y signal(S) después para prevenir acceso del cliente También realiza signal(N) después de cada append para incrementar N El consumidor primero debe hacer wait(N) para ver si hay un item para consumir y usar wait(S)/signal(S) para accesar el buffer

59 59/111 Solución de P/C: buffer ilimitado Producer: repeat produce v; wait(S); append(v); signal(S); signal(N); forever Consumer: repeat wait(N); wait(S); w:=take(); signal(S); consume(w); forever Initialization: S.count:=1; N.count:=0; in:=out:=0; Secciones criticas append(v): b[in]:=v; in++; take(): w:=b[out]; out++; return w;

60 60/111 P/C: buffer ilimitado Comentarios:  Poniendo signal(N) dentro del CS del productor (en lugar de afuera), no tiene efecto desde que el consumidor siempre debe esperar por ambos semáforos antes de proceder  El consumidor debe ejecutar wait(N) antes del wait(S), en caso contrario deadlock ocurre si el consumidor entra en CS mientras el buffer está vacío Usar semáforos es un arte difícil...

61 61/111 P/C: buffer circular finito de tamaño k Puede consumir solamente cuando el número N de items (consumible), es por lo menos 1 (ahora: N!=in-out) Puede producir solamente cuando el número E de espacios vacíos es por lo menos 1

62 62/111 P/C: buffer circular finito de tamaño k Como antes:  Se necesita un semáforo S para tener exclusión mutua en acceso al buffer  Se necesita un semáforo N para sincronizar productor y consumidor en el número de items consumibles Además:  Se necesita un semáforo E para sincronizar productor y consumidor en el número de espacios vacíos

63 63/111 Solución de P/C: buffer circular finito de tamaño k Initialization: S.count:=1; in:=0; N.count:=0; out:=0; E.count:=k; Producer: repeat produce v; wait(E); wait(S); append(v); signal(S); signal(N); forever Consumer: repeat wait(N); wait(S); w:=take(); signal(S); signal(E); consume(w); forever Secciones criticas append(v): b[in]:=v; in:=(in+1) mod k; take(): w:=b[out]; out:=(out+1) mod k; return w;

64 64/111 El problema de los Filósofos Cenando 5 filósofos que sólo comen y piensan Cada uno necesita usar 2 tenedores para comer Se tienen sólo 5 tenedores Un problema clásico de sincronización Ilustra la dificultad de asignar recursos entre procesos sin deadlock y sin inanición

65 65/111 El problema de los Filósofos Cenando Cada filósofo es un proceso Un semáforo por tenedor (fork):  fork: array[0..4] de semáforos  Inicialización: fork[i].count:=1 para i:=0..4 Un primer intento: ¡Deadlock si cada filósofo comienza escogiendo su tenedor izquierdo! Process Pi: repeat think; wait(fork[i]); wait(fork[i+1 mod 5]); eat; signal(fork[i+1 mod 5]); signal(fork[i]); forever

66 66/111 El problema de los Filósofos Cenando Solución 1: Se podría modificar el programa de forma que después de tomar el tenedor izquierdo, el programa verifique si el tenedor derecho está disponible. Si no, el filósofo deja el tenedor izquierdo, espera cierto tiempo y vuelve a repetir todo el proceso

67 67/111 El problema de los Filósofos Cenando Solución 1:  Falla: por cuanto podría pasar que todos los filósofos podrían comenzar el algoritmo en forma simultánea, recogerían sus tenedores izquierdos, verían que los derechos no están disponibles, dejarían sus tenedores izquierdos, esperarían, volverían a recoger sus tenedores izquierdos en forma simultánea, etc, eternamente  Una situación como esta, en la que todos los programas se mantendrían en ejecución por tiempo indefinido sin hacer progresos, se llama INANICION

68 68/111 El problema de los Filósofos Cenando Solución 2: admita a sólo 4 filósofos que intentan comer en un momento Luego 1 filósofo siempre puede comer cuando los otros 3 están manteniendo 1 tenedor De lo anterior, se puede usar otro semáforo T que limitaría a 4 el número de filósofos “sentados en la mesa” Inicialice: T.count:=4 Process Pi: repeat think; wait(T); wait(fork[i]); wait(fork[i+1 mod 5]); eat; signal(fork[i+1 mod 5]); signal(fork[i]); signal(T); forever

69 69/111 Semáforos binarios Los semáforos estudiados son llamados semáforos enteros (o counting) Se tienen también semáforos binarios  Similar a semáforos enteros (counting) excepto que “count” es un valor Booleano  Semáforos enteros pueden ser implementados por semáforos binarios...  Generalmente más difícil de usar que semáforos enteros (ellos no pueden ser inicializados con un entero k> 1)

70 70/111 Semáforos binarios waitB(S): if (S.value = 1) { S.value := 0; } else { block this process place this process in S.queue } signalB(S): if (S.queue is empty) { S.value := 1; } else { remove a process P from S.queue place this process P on ready list }

71 71/111 Spinlocks Existen semáforos enteros que usan espera ocupada (en lugar de bloquear) Útil en multiprocesadores cuando las secciones críticas duran un tiempo corto Se gasta un quantum de tiempo de CPU pero se ahorra el intercambio de procesos wait(S): S--; while S<0 do{}; signal(S): S++;

72 72/111 Problemas con semáforos Los semáforos proveen una herramienta poderosa para forzar la exclusión mutua y para coordinar procesos Pero wait(S) y signal(S) están dispersos entre varios procesos. De aquí que sea difícil de entender sus efectos El uso debe ser correcto en todos los procesos Un proceso malo (o malévolo) puede fallar la colección completa de procesos

73 73/111 Monitor Son construcciones de lenguajes de alto nivel, las cuales proporcionan funcionalidad equivalente a la de semáforos pero son más fácil controlar Encontrado en muchos lenguajes de programación concurrente Pascal concurrente, Modula-3, uC++, Java... Puede ser implementado por semáforos...

74 74/111 Monitor Es un módulo de software conteniendo:  Uno o más procedimientos  Una secuencia de inicialización  Variables locales Características:  Variables locales accesibles solamente por los procedimientos del monitor  Un proceso entra en el monitor invocando uno de sus procedimientos  Solamente un proceso puede estar en el monitor en cualquier un momento

75 75/111 Monitor El monitor asegura exclusión mutua: no se necesita programar esta restricción explícitamente De lo anterior, los datos compartidos son protegidos poniéndolos en el monitor  El monitor bloquea (locks) los datos compartidos en la entrada del proceso (process entry) La sincronización del proceso es realizada por el programador, usando variables de condición que representan condiciones. Un proceso puede necesitar esperar antes de ejecutarse en el monitor

76 76/111 Variables de condición Son locales al monitor (accesible sólo dentro del monitor) Solamente pueden ser accesadas y cambiadas por dos funciones:  cwait(a): bloquea la ejecución del proceso que llama sobre la condición (variable) a El proceso sólo puede reasumir la ejecución si otro proceso ejecuta csignal(a)  csignal(a): reasume la ejecución de algún proceso bloqueado sobre la condición (variable) a. Si varios de tales procesos existen: escoja cualquiera Si ninguno de tales procesos existe: no haga nada

77 77/111 Los procesos que esperan (awaiting processes) están en la cola de entrada o, en una cola de condición Un proceso se pone en la cola de condición cn, emitiendo un cwait(cn) csignal(cn) pone dentro del monitor, 1 proceso en cola de condición cn De lo anterior, csignal(cn) bloquea al proceso que llama y lo pone en la cola urgente (a menos que el csignal sea la última operación del procedimiento del monitor) Monitor

78 78/111 Problema del Productor/Consumidor Dos tipos de procesos:  productores  consumidores La sincronización se confina ahora dentro del monitor append(.) y take(.) son procedimientos dentro del monitor: son los únicos medios por el cual P/C puede accezar el buffer Si estos procedimientos son correctos, la sincronización será correcta para todos los procesos que participan ProducerI: repeat produce v; Append(v); forever ConsumerI: repeat Take(v); consume v; forever

79 79/111 Monitor para el problema de P/C limitado El monitor necesita mantener el buffer:  buffer: array[0..k-1] de items; Se necesitan dos variables de condición:  notfull: csignal(notfull) indica que el buffer no está lleno  notempty: csignal(notempty) indica que el buffer no está vacío Se necesitan apuntadores al buffer y counts:  nextin: apunta al próximo item que será añadido (appended)  nextout: apunta al próximo item que será ser tomado  count: mantiene el número de items en el buffer

80 80/111 Monitor para el problema de P/C limitado Monitor boundedbuffer: buffer: array[0..k-1] of items; nextin:=0, nextout:=0, count:=0: integer; notfull, notempty: condition; Append(v): if (count=k) cwait(notfull); buffer[nextin]:= v; nextin:= nextin+1 mod k; count++; csignal(notempty); Take(v): if (count=0) cwait(notempty); v:= buffer[nextout]; nextout:= nextout+1 mod k; count--; csignal(notfull);

81 81/111 Monitor para el problema de P/C limitado Un productor sólo puede añadir caracteres al buffer por medio de Append(x). El productor no tiene acceso directo al buffer El procedimiento comprueba primero la condición No-lleno para determinar si hay espacio libre en el buffer  Si no lo hay, el proceso que está ejecutando el monitor se suspende en esa condición  Cualquier otro proceso (productor/consumidor) puede entrar al monitor

82 82/111 Monitor para el problema de P/C limitado El procedimiento comprueba primero la condición No-lleno para determinar si hay espacio libre en el buffer  Cuando el buffer ya no esté lleno, el proceso suspendido podrá ser retirado de la cola, reactivado y el procesamiento podrá reanudarse  Después de poner un carácter en el buffer, el proceso activa la condición No-vacío

83 83/111 Monitor. Características Es posible cometer errores en la sincronización  Ejemplo: Si se omite cualquiera de las funciones Csignal en el monitor buffer-limitado, los procesos que entran en la cola de la condición correspondiente, permanecerán colgado, esperando permanentemente Las funciones de sincronización están confinadas dentro del monitor (es sencillo verificar que la sincronización se ha realizado correctamente y detectar fallas)

84 84/111 Monitor. Características Una vez que el monitor está correctamente programado, el acceso al recurso protegido es correcto para todos los procesos (con semáforos, el acceso al recurso es correcto sólo si todos los procesos que acceden al recurso, están correctamente programados)

85 85/111 Monitores con Notificación y Difusión Si hay al menos un proceso en una cola de condición, un proceso de dicha cola se deberá ejecutar en cuanto otro proceso ejecute un Csignal para la condición (def. de Hoare) El proceso que ejecuta el Csignal, debe salir del monitor o suspenderse en el monitor

86 86/111 Monitores con Notificación y Difusión Inconvenientes  Si el proceso que ejecuta un Csignal no abandona el monitor, hacen falta 2 cambios de contexto adicionales (uno para suspender el proceso y otro para reanudar)  Cuando se ejecuta un Csignal, debe activarse inmediatamente un proceso de la cola de condición correspondiente y el planificador debe asegurarse que ningún otro proceso entre al monitor antes de la activación; sino, se corre el riesgo de quedarse colgado, esperando, para siempre

87 87/111 Monitores con Notificación y Difusión Solución Lampson Redell (desarrollo de una definición diferente de monitores para el lenguaje Mesa) La primitiva Csignal se reemplaza por Cnotify con la siguiente interpretación: Cuando un proceso que está en el monitor ejecuta un Cnotify, origina una notificación hacia la cola de la condición x, pero el proceso que da la señal puede continuar ejecutando

88 88/111 Monitores con Notificación y Difusión El resultado de la notificación es que el proceso de la cabeza de la cola de condición, será reanudado en el futuro cercano, cuando el monitor este disponible y el proceso que espera debe volver a comprobar la condición

89 89/111 Monitor para el problema de P/C limitado Monitor boundedbuffer: buffer: array[0..k-1] of items; nextin:=0, nextout:=0, count:=0: integer; notfull, notempty: condition; Append(v): While (count=k) cwait(notfull); buffer[nextin]:= v; nextin:= nextin+1 mod k; count++; cnotify(notempty); Take(v): While (count=0) cwait(notempty); v:= buffer[nextout]; nextout:= nextout+1 mod k; count--; cnotify(notfull);

90 90/111 Monitor para el problema de P/C limitado Esta modificación genera al menos una evaluación extra de la variable de condición Para evitar la inanición (en caso de que algún proceso falle antes de señalar una condición), se establece un temporizador de guarda asociado con cada primitiva Cnotify sobre la condición. Un proceso que ha estado esperando durante el intervalo máximo de guarda, será situado en el estado de listo independientemente si se ha notificado la condición

91 91/111 Monitores Cbroadcast: primitiva de difusión, la cual provoca que todos los procesos que están esperando por una condición, se sitúen en el estado de listo  Conveniente en situaciones donde un proceso, no sabe cuántos procesos deben reactivarse  Puede emplearse en casos en los que un proceso tenga dificultades para averiguar exactamente a que otro proceso tiene que reactivar  Ejem: gestor de memoria:

92 92/111 Paso de mensaje Es un método general usado para la comunicación entre procesos (IPC)  Para los procesos dentro del mismo computador  Para los procesos en un sistema distribuido Significa otra manera de proveer sincronización y exclusión mutua de procesos Se tienen por lo menos dos primitivas:  send(destino, mensaje)  received(fuente, mensaje) En ambos casos, el proceso puede o no puede bloquearse

93 93/111 Sincronización en paso de mensaje Para el emisor (sender): es más natural no ser bloqueado después de emitir send(.,.)  Puede enviar varios mensajes a múltiple destinos  Pero el emisor usualmente espera el reconocimiento del acuse de recibo del mensaje (en caso de que el receptor falle) Para el receptor: es más natural ser bloqueado después de emitir receive(.,.)  El receptor usualmente necesita la información antes de proceder  Pero podría bloquearse indefinidamente si el proceso sender falla antes de send(.,.)

94 94/111 Sincronización en paso de mensaje A veces se ofrecen otras posibilidades Ejem: bloqueando send y bloqueando receive:  Ambos son bloqueados hasta que el mensaje sea recibido  Ocurre cuando el enlace de comunicación es unbuffered (ningún mensaje encolado)  Proporciona sincronización segura (rendez- vous)

95 95/111 Direccionamiento en paso de mensaje Direccionamiento directo:  Cuando un identificador de proceso específico se usa para el fuente/destino  Pero podría ser imposible especificar el fuente adelantado (ejem: un servidor de impresión) Direccionamiento indirecto (más conveniente):  Se envían mensajes a un buzón compartido que consiste en una cola de mensajes  Los remitentes ponen mensajes en el buzón, los receptores los recogen

96 96/111 Buzones y Puertos Un buzón puede ser privado a un par remitente/receptor El mismo buzón puede compartirse entre varios remitentes y receptores  El OS entonces, puede permitir el uso de tipos de mensaje (por selección) Puerto: es un buzón asociado con un receptor y múltiples remitentes  Usado para aplicaciones cliente/servidor: el receptor es el servidor

97 97/111 Propiedad de puertos y buzones Un puerto es usualmente creado y apropiado por el proceso receptor El puerto se destruye cuando el receptor termina El OS crea un buzón en nombre de un proceso (qué se vuelve el dueño) El buzón se destruye mediante un requerimiento del dueño o cuando el dueño termina

98 98/111 Formato del mensaje Consiste de encabezado y cuerpo del mensaje En Unix: ningún ID, sólo tipo del mensaje Información de control:  Que hacer si se ejecuta fuera del espacio del buffer  Números de secuencia  Prioridad... Disciplina de la cola: usualmente FIFO pero también puede incluir prioridades

99 99/111 Exclusión mutua forzando paso de mensaje Cree un buzón mutex compartido por n procesos send() no es bloqueante receive() se bloquea cuando mutex está vacío Inicialización: send(mutex, “go”); El primer Pi que ejecuta receive() entrará en CS. Los otros se bloquearán hasta que Pi reenvie el mensaje Process Pi: var msg: message; repeat receive(mutex,msg); CS send(mutex,msg); RS forever

100 100/111 El problema P/C de buffer limitado con paso de mensaje Ahora se hará uso de mensajes El productor pondrá items (dentro de los mensajes) en el buzón mayconsume mayconsume actúa como un buffer: el consumidor puede consumir items cuando al menos un mensaje está presente

101 101/111 El problema P/C de buffer limitado con paso de mensaje El buzón mayproduce está inicialmente lleno con k mensajes nulos (k=tamaño del buffer) El tamaño de mayproduce disminuye con cada producción y crece con cada consumo Puede soportar múltiples productores y consumidores

102 102/111 El problema P/C de buffer limitado con paso de mensaje Producer: var pmsg: message; repeat receive(mayproduce, pmsg); pmsg:= produce(); send(mayconsume, pmsg); forever Consumer: var cmsg: message; repeat receive(mayconsume, cmsg); consume(cmsg); send(mayproduce, null); forever

103 103/111 Unix SVR4 mecanismos de concurrencia Para comunicar datos a través de procesos:  Pipes  Mensajes  Memoria compartida Para activar acciones a través de otros procesos:  Signals  Semáforos

104 104/111 Pipes Unix Una cola FIFO limitada compartida (shared bounded) escrita por un proceso y leído por otro  Basado en el modelo productor/consumidor  OS fuerza Exclusión Mutua: sólo un proceso en un momento puede acceder el pipe  Si no hay suficiente espacio para escribir, el productor se bloquea, en caso contrario, escribe  El consumidor se bloquea si intenta leer más bytes de los que actualmente están en el pipe  Accesado como un descriptor de archivo, es igual a un archivo común  Los procesos que comparten el pipe no conocen la existencia de cada uno de los otros

105 105/111 Mensajes Unix Un proceso puede crear o puede acceder a una cola de mensajes (como un buzón) con la llamada del sistema msgget. Se usan las llamadas de sistema msgsnd y msgrcv para enviar y recibir mensajes a una cola Existe un campo “tipo” en el encabezado del mensaje  Acceso FIFO dentro de cada tipo del mensaje  Cada tipo define un canal de comunicación El proceso es bloqueado (puesto a dormir) cuando:  Intenta recibir de una cola vacía  Intenta enviar a una cola llena

106 106/111 Memoria compartida en Unix Un bloque de memoria virtual compartida por múltiples procesos La llamada del sistema shmget, crea una nueva región de memoria compartida o retorna una existente Un proceso anexa (attaches) una región de memoria compartida a su espacio de dirección virtual con la llamada del sistema shmat La exclusión mutua debe ser proporcionada por procesos que usan la memoria compartida Es la forma más rápida de IPC proporcionada por Unix

107 107/111 Signals Unix Similar a las interrupciones de hardware sin prioridades Cada signal está representada por un valor numérico. Ejemplo:  02= SIGINT: para interrumpir un proceso  09= SIGKILL: para terminar un proceso Cada signal se mantiene como un simple bit (single bit) en la entrada de la tabla de procesos, del proceso receptor: el bit es colocado en 1 (set) cuando el signal correspondiente llega (ninguna cola de espera) Un signal se procesa tan pronto como el proceso se ejecute en modo usuario Una acción por defecto (ejemplo: terminación) se realiza, a menos que una función manipuladora de signal sea proporcionada para esa signal (usando la llamada del sistema signal)

108 108/111 Semáforos Unix Son una generalización de los semáforos counting (más operaciones son permitidas). Un semáforo incluye:  El valor actual S del semáforo  Número de procesos que esperan por que S sea mayor que cero  Número de procesos que esperan por que S sea igual a cero

109 109/111 Semáforos Unix Se tienen colas de procesos que se bloquean en un semáforo La llamada del sistema semget, crea un arreglo de semáforos La llamada de sistema semop realiza una lista de operaciones: uno en cada semáforo (atómicamente)

110 110/111 Semáforos Unix Cada operación a ser realizada, es especificada por un valor sem_op Dado S a ser el valor del semáforo  if sem_op > 0: S es incrementado y el proceso espera por que S sea incrementado es despertado  if sem_op = 0: If S=0: no haga nada if S!=0, bloquee el proceso actual esperando por el evento que S=0

111 111/111 Semáforos Unix  if sem_op < 0 and |sem_op| <= S: set S:= S + sem_op (es decir: S disminuye) Luego si S=0: se despiertan los procesos que esperan por S=0  if sem_op S: el proceso actual se bloquea en el evento que S sea mayor que cero Lo anterior implica una gran flexibilidad de uso, ya que son permitidas muchas operaciones


Descargar ppt "1 Concurrencia: Exclusión mutua y Sincronización."

Presentaciones similares


Anuncios Google