Semforos Cecilia Hernndez 2007 1 Semforos Primitiva de

  • Slides: 24
Download presentation
Semáforos Cecilia Hernández 2007 -1

Semáforos Cecilia Hernández 2007 -1

Semáforos ¢ Primitiva de Sincronización propuesta por Dijkstra en 1968 l l l ¢

Semáforos ¢ Primitiva de Sincronización propuesta por Dijkstra en 1968 l l l ¢ Como parte de sistema THE Usados para exclusión mutua y planificación De nivel más alto que locks Variable atómica manipulada por dos operaciones l Wait(semaforo) • Decrementa semáforo • Bloquea hebra/proceso si el semáforo es menor que cero, sino entonces permite a hebra/proceso continuar • Operacion tambien llamada P(semaforo) o down(semaforo) l Signal(semáforo) • Incrementa semáforo en uno y si hay algún proceso/hebra esperando lo despierta • También llamada V(semaforo) o up(semaforo) l Valor de semáforo puede ser mayor que 1 • Inicializado en 1 es como lock. • Usado para exclusión mutua • Inicializado en N • Usado como contador atómico

Implementación de Semáforos typedef struct { int value; struct hebra *L; } semaphore; void

Implementación de Semáforos typedef struct { int value; struct hebra *L; } semaphore; void wait(semaphore S) { S. value--; if (S. value < 0){ agregar hebra a S. L; block(); } } void signal(semaphore S){ S. value++; if (S. value <= 0){ remover hebra T de S. L; wakeup(T); } }

Exclusión mutua vs planificación Exclusión mutua - Sólo una hebra a la vez en

Exclusión mutua vs planificación Exclusión mutua - Sólo una hebra a la vez en SC - Puede ser cualquier hebra lock Sección crítica unlock Planificación - Requerimiento de orden en ejecución de hebras. tiempo

Ejemplo planificación tiempo H 1. imprime A sem S 1 = 0, S 2

Ejemplo planificación tiempo H 1. imprime A sem S 1 = 0, S 2 = 0 H 1: H 2: print A; wait(S 1); signal(S 1); print B; signal(S 2); H 3: wait(S 2); print C; H 2. imprime B H 3. imprime C

Tipos de Semáforos ¢ ¢ Binarios (mutex) l Garantizan exclusión mutua a recurso l

Tipos de Semáforos ¢ ¢ Binarios (mutex) l Garantizan exclusión mutua a recurso l Sólo una hebra/proceso puede accesar sección crítica a la vez l Contador de semáforo inicializado en 1 Contadores l Representan recursos con más de una unidad disponible l Permiten accesar recursos de acuerdo al número de recursos disponibles l Contador es inicializado en N, donde N es la cantidad de unidades disponibles del recurso

Ejemplos Clásicos de Sincronización ¢ Problema Productor/Consumidor l Un buffer en memoria con N

Ejemplos Clásicos de Sincronización ¢ Problema Productor/Consumidor l Un buffer en memoria con N slots disponibles • Necesita llevar cuenta de ítemes en buffer l l Productor produce ítemes a ingresar al buffer Consumidor consume ítemes del buffer P C Consumidor Remueve item usando puntero out Productor Agrega item usando puntero in out in

Algoritmo Productor/Consumidor int contador = 0; //indica número de items en buffer Tipo buffer[N];

Algoritmo Productor/Consumidor int contador = 0; //indica número de items en buffer Tipo buffer[N]; int in = 0; int out = 0; Productor Consumidor while (true) { /* produce un item en prox. Prod */ while (contador == N); //espera buffer[in] = prox. Prod; in = (in + 1) % N; contador++; } while (true) { while (contador == 0); //espera prox. Cons = buffer[out]; out = (out + 1) % N; contador--; /* consume prod. Cons */ }

Cómo resolver problema? ¢ Identificar restricciones inherentes al problema l Estado compartido? • contador

Cómo resolver problema? ¢ Identificar restricciones inherentes al problema l Estado compartido? • contador (consumidores y productores) • Buffer • in ( productores). Productores no pueden insertar en buffer lleno • out ( consumidores). Consumidores no pueden extraer de buffer vacío ¢ ¢ Posible resolver con locks? Si Posible resolver con semáforos? Si

Cómo resolver problema? ¢ Identificar estado compartido y restricciones de problema l l l

Cómo resolver problema? ¢ Identificar estado compartido y restricciones de problema l l l l Buffer de tamaño limitado compartido entre productores y consumidores Productor escribe en buffer[in], in indica posición de escritura en buffer Consumidor extrae de buffer[out], out indica posición de extracción de buffer Contador indica el número de elementos actuales en el buffer Múltiples productores deben manipular in, buffer[in] y contador atómicamente. Múltiples consumidores deben manipular out, buffer[out] y contador atómicamente Múltiples consumidores y productores deben manejar contador atómicamente

Solución Productor/Consumidor usando locks int contador = 0; //indica número de items en buffer

Solución Productor/Consumidor usando locks int contador = 0; //indica número de items en buffer char buffer[N]; int in = 0; int out = 0; lock_t mutex; Productor while (true) { /* produce un item en prox. Prod */ lock(mutex); while(contador == N){ unlock(mutex); yield(); } buffer[in] = prox. Prod; in = (in + 1) % N; contador++; unlock(lock); } Consumidor While(true){ lock(mutex); while(contador == 0){ unlock(mutex); yield(); } prox. Cons = buffer[out]; out = (out + 1) % N; contador--; unlock(mutex); /* consume prox. Cons */ }

Solución usando semáforos ¢ Identificar estado compartido y restricciones de problema l ¢ Especificar

Solución usando semáforos ¢ Identificar estado compartido y restricciones de problema l ¢ Especificar condiciones de espera y señalización l l l ¢ Cuando buffer está lleno productores deben esperar a que exista una posición vacía (generada por un consumidor) Cuando buffer esta vacío consumidores deben esperar a que exista un elemento en el buffer (generado por un productor) Acceso a buffer y contador debe realizarse atómicamente Identificar semáforos para proveer sincronización l l l ¢ Ya presentadas Mutex (inicializado en 1): para exclusión mutua de buffer, in, out y contador. Full (inicializado en 0). Para indicar cuántas posiciones llenas hay en el buffer Empty (inicializado en N). Para indicar cuantas posiciones vacías hay en el buffer Proporcionar algoritmos

Solución usando semáforos int contador = 0; //indica número de items en buffer char

Solución usando semáforos int contador = 0; //indica número de items en buffer char buffer[N]; int in = 0; int out = 0; sem mutex=1; sem vacio = N; sem lleno = 0; Productor while (true) { /* produce un item en prox. Prod */ wait(vacio); wait(mutex); buffer[in] = prox. Prod; in = (in + 1) % N; contador++; signal(mutex); signal(lleno); } Consumidor While(true){ wait(lleno); wait(mutex); prox. Cons = buffer[out]; out = (out + 1) % N; contador--; signal(mutex); signal(vacio); /* consume prox. Cons */ }

Ejemplos ¢ Productor/consumidor usando pthreads y locks l ¢ http: //www. inf. udec. cl/~chernand/sc/ej

Ejemplos ¢ Productor/consumidor usando pthreads y locks l ¢ http: //www. inf. udec. cl/~chernand/sc/ej emplos/prodcons. Locks. C Productor/consumidor usando pthreads y semáforos l http: //www. inf. udec. cl/~chernand/sc/ej emplos/prodcons. Sem. C

Problema lectores/escritor ¢ Caso base de datos l l Varios lectores pueden accesar registro

Problema lectores/escritor ¢ Caso base de datos l l Varios lectores pueden accesar registro datos simultaneamente Sólo un escritor puede escribir L E Registro BD L

Cómo resolver problema? ¢ Identificar estado compartido y restricciones de problema l Base de

Cómo resolver problema? ¢ Identificar estado compartido y restricciones de problema l Base de datos compartida • Mientras haya un lector un escritor no puede accesar base de datos • Mientras exista un escritor en base de datos ningún otro escritor o lector puede accesarla ¢ Identificar condiciones de espera y señalización l l l Si existe un escritor en BD otro escritor o lector debe esperar Cuando un escritor termina debe señalizar escritor o lector que espera Si podemos tener varios lectores debemos contarlos, para saber cuando existe uno • Si hay uno leyendo y llegan otros, otros tambien pueden leer • Si solo hay uno y sale puede haber un escritor esperando accesar BD ¢ Qué semáforos necesitamos l l Uno inicializado en 1 como mutex para manejar contador de lectores Uno tipo mutex para escritor y primer lector

Algoritmo usando semáforos sem mutex=1; sem escribir = 1; Int contador. Lectores = 0;

Algoritmo usando semáforos sem mutex=1; sem escribir = 1; Int contador. Lectores = 0; Escritor: wait(escribir); espera por escritor o lector Escritor_escribe; Escribe objeto signal(escribir); permite leer y/o escribir a otros, escritura completada Lector: wait(mutex); asegura acceso exclusivo a contador de lectores contador. Lectores = contador. Lectores++; incrementa lectores if(contador. Lectores == 1) then wait(escribir); Si es el primer lector espera si hay escritor signal(mutex); Lector_lee; wait(mutex); asegura acceso exclusivo a contador de lectores contador. Lectores = contador. Lectores--; lector terminó de leer if(contador. Lectores == 0) then signal(escribir); no mas lectores por si escritor esperaba signal(mutex)

Notas sobre Lectores/Escritores ¢ ¢ ¢ Primer lector se bloquea si hay un escritor

Notas sobre Lectores/Escritores ¢ ¢ ¢ Primer lector se bloquea si hay un escritor activo l cualquier otro escritor se bloquea también Si un escritor espera porque existen lectores activos, el último lector lo despierta cuando sale l pueden otros lectores entrar cuando el escritor está esperando? Cuando un escritor sale, si hay un escritor y un lector esperando quien entra?

Otro ejemplo clásico ¢ Problema de Filósofos comensales l l ¢ Cada filósofo tiene

Otro ejemplo clásico ¢ Problema de Filósofos comensales l l ¢ Cada filósofo tiene su plato de arroz, con 5 palitos 5 filósofos se sientan a la mesa. Piensan por un rato y cuando les da hambre comen Hay sólo 5 palitos en la mesa (cada persona necesita 2 palitos para comer arroz a la manera china) Para poder comer cada filósofo tiene que obligatoriamente conseguir dos palitos Problema es importante porque introduce posibles problemas de Deadlock(bloqueo mortal) y Starvation(inanición)

Problema de Filósofos comensales

Problema de Filósofos comensales

Problemas que pueden surgir con mala sincronización ¢ Deadlock l Hebras/Procesos están en deadlock

Problemas que pueden surgir con mala sincronización ¢ Deadlock l Hebras/Procesos están en deadlock cuando • 2 o más hebras o procesos están esperando por una condición que sólo puede ser causada por una hebra que tambien está esperando. • Puede darse con 2 o más hebras en la lista de espera de un mismo semáforo? ¢ Starvation o espera indefinida l Hebras/Procesos esperan indefinidamente para poder accesar un recurso. • Ejemplo, una hebra en la lista de espera de un semáforo de la cual están entrando y saliendo continuamente hebras y la lista de espera de semáforo es LIFO

Ejemplo deadlock con productor/consumidor int contador = 0; //indica número de items en buffer

Ejemplo deadlock con productor/consumidor int contador = 0; //indica número de items en buffer char buffer[N]; int in = 0; int out = 0; sem mutex=1; sem vacio = N; sem lleno = 0; Productor while (true) { /* produce un item en prox. Prod */ wait(mutex); wait(vacio); buffer[in] = prox. Prod; in = (in + 1) % N; contador++; signal(mutex); signal(lleno); } Que sucede aquí? Consumidor While(true){ wait(lleno); wait(mutex); prox. Cons = buffer[out]; out = (out + 1) % N; contador--; signal(mutex); signal(vacio); /* consume prox. Cons */ }

Problemas con Semáforos ¢ A pesar que se pueden usar para resolver cualquier problema

Problemas con Semáforos ¢ A pesar que se pueden usar para resolver cualquier problema de sincronización l Son variables globales por lo tanto pueden ser accesadas de cualquier hebra directamente • no es buena técnica de ingeniería de software l l l No hay conexión entre el semáforo y el recurso para el cual se quiere controlar acceso Usados como mutex (ingreso a sección crítica) y para coordinación (planificación, elección quien tiene acceso al recurso) No se puede controlar su uso, no hay garantía que el programador los use adecuadamente (fácil de cometer errores)

Resumen ¢ ¢ ¢ Semáforos primitivas de sincronización de más alto nivel que locks

Resumen ¢ ¢ ¢ Semáforos primitivas de sincronización de más alto nivel que locks No relación entre semáforo y recurso que controla Fácil de cometer errores que pueden producir deadlock y starvation l ¢ Importante entender bien problema antes de utilizarlos Próxima semana Monitores