Herramientas de Desarrollo en Informática Primitivas de

Anuncio
Herramientas de Desarrollo en Informática
Primitivas de sincronización (continuación)
Implementación de los problemas clásicos utilizando semáforos
1.­ Productor ­ consumidor
Este problema requiere sincronizar los procesos productor y consumidor. La siguiente implementación es únicamente para un productor y un consumidor:
Program Prod­Cons() {
/* Declaraciones e inicializaciones */
shared semaphore producidos = 0;
shared semaphore libres = n;
shared int in = 0;
shared int out = 0;
shared int buffer[n];
Procedure Productor(){
item i;
for(;;){
i = produce();
wait(libres);
buffer[in] = i;
in = (in + 1)%n;
signal (producidos);
}
}
}
Procedure Consumidor(){
item i;
for (;;){
wait(producidos);
i = buffer[out];
out = (out + 1)%n;
signal(libres);
consumir(i);
}
}
begin
ParBegin()
Productor();
Consumidor();
ParEnd();
End
in = out ⇒ libres = n ∨ producidos = n (el buffer está vacío ó esta lleno)
Para muchos productores y un solo consumidor, el programa anterior debe modificarse agregando un nuevo semáforo ( mutex ) para controlar la exclusión mutua en al región crítica del proceso productor. El programa modificado es el siguiente:
Program Prod­Cons(){
/* Declaraciones e inicializaciones */
shared semaphore producidos = 0;
shared semaphore libres = n;
shared semaphore mutex = 1;
shared int in = 0;
shared int out = 0;
shared int buffer[n];
Procedure Productor(){
item i;
for(;;){
i = produce();
wait(libres);
wait (mutex);
buffer[in] = i;
in = (in + 1)%n;
signal(mutex);
signal (producidos);
}
}
Procedure Consumidor(){
item i;
for (;;){
wait(producidos);
i = buffer[out];
out = (out + 1)%n;
signal(libres);
consumir(i);
}
}
begin
ParBegin()
Productor();
Consumidor();
ParEnd();
}
End
Asignaciones: ­ Realizar la solución del problema para más de un productor y más de un consumidor.
2.­ Lectores ­ escritores
2.1 ­ Con prioridad a los lectores
/* variables e inicializaciones */
semaphore w = 1; /* número de escritores */
semaphore lmutex = 1;
int ar = 0; /* número de lectores activos */
Lectores(){
wait (lmutex);
ar = ar + 1;
if ar = 1 then /* Si es el primer lector */
wait (w);
signal(lmutex);
Realizar Lectura;
wait(lmutex);
ar = ar ­ 1;
if (ar = 0) then /* Si es el último lector. Esto es para signal (w); evitar signals innecesarios */
signal (lmutex);
}
Escritores(){
wait(w);
Realizar Escritura;
signal(w);
}
2.2 ­ Con prioridad a los escritores
/* variables e inicialización */
semaphore r = 0;
semaphore w = 0; semaphore wmutex = 1;
semaphore lmutex = 1;
int ar = 0; /* número de lectores activos */
int rr = 0; /* número de procesos que están "leyendo" */
int aw = 0; /* número de escritores activos */
int ww = 0; /* número de procesos "escribiendo". Esta variable es binaria ya que sólo puede haber un proceso escribiendo a la vez */
Lectores(){
wait(lmutex);
ar = ar + 1;
if aw = 0 then {
rr = rr + 1;
signal (r);
}
signal(lmutex);
}
wait (r);
Realizar Lectura;
wait(lmutex);
rr = rr ­ 1;
ar = ar ­ 1;
if rr = 0 then
while ww < aw {
ww = ww + 1;
signal(w);
}
signal (lmutex);
Escritores(){
wait(lmutex);
aw = aw + 1;
if rr = 0 then
{
ww = ww + 1;
signal(w);
}
signal(lmutex);
wait (w);
wait (wmutex);
Realizar Escritura;
signal(wmutex);
wait(lmutex);
aw = aw ­ 1;
ww = ww ­ 1;
if aw = 0 then
while rr < ar {
rr = rr + 1;
signal (r);
}
signal(lmutex);
}
En esta implementación los lectores y escritores entran según estén encolados .
3.­ Barbero dormilón
/* Inicialización de los semáforos */
semaphore clientes = 0; /* Número de clientes en espera del servicio */ semaphore barbero = 0; /* Los clientes esperan por este semáforo */
semaphore mutex = 1;
/* variables */
int esperando = 0; /* número de clientes en espera. Esta variable es una copia del semáforo clientes que se utiliza para verificar si hay o no sillas vacías */
Barbero() {
while(true) {
wait (clientes); /* Duerme si no hay clientes */
wait (mutex);
esperando ­­;
signal(barbero); /* Está listo para cortar el cabello */
signal(mutex);
cut_hair();
}
}
Clientes(){
wait(mutex);
if (esperando < NUM_SILLAS) then /* Se va si no hay sillas { desocupadas */
esperando ++;
signal(clientes); /* Despierta al barbero si es necesario */
signal(mutex);
wait(barbero); /* Duerme si el barbero está ocupado */ get_hair_cut();
}
else
signal(mutex);
}
Asignación: Realizar el problema para muchos barberos y muchos clientes.
4.­ Cena de los filósofos
/* Semáforos */
chopstick array[0 .. 4] of Sem = {1,1,1,1}
Filósofo() {
loop {
Pensar;
wait (chopstick[(i+1)%5]);
wait (chopstick[(i­1)%5]);
Comer;
signal(chopstick[(i+1)%5]);
signal(chopstick[(i­1)%5]);
}
}
Descargar