You are on page 1of 5

Pr

actica semanal 3
Panaderia Lamport
Autor: Jose Manuel Luque Gonzalez
Dise
no de sistemas concurrentes y distribuidos

1.

Dependiente.java

El dependiente es una clase cuyo objetivo es bastante simple, u


nicamente se dedica a
mirar cuando tiene 2 clientes dentro.
package pkgPanaderia;
public class Dependiente
{
public void Atender(int id) throws ExceptionClientes
{
Panaderia.clientesdentro++;
System.out.println("Atiendo al cliente "+ id);
if (Panaderia.clientesdentro>=2)
{
Panaderia.clientesdentro=--; //Voy a echar a este cliente
Panaderia.NumFallo++;
//Sumo el fallo
throw new ExceptionClientes(); //Lanzo excepcion
}
Panaderia.clientesdentro--;
}
}
Cuando haya 2 o mas clientes siendo atendidos lanzara una excepcion cuya finalidad es
avisarme de que esto ha ocurrido, ademas aumentara el contador de fallos y quitara mnimo uno de los clientes (si se da el caso de un cambio de contexto especfico puede echar
a los 2 clientes que han entrado a la vez, lo cual aumentara la variable de fallos dos
veces) en general, solamente echara al primero. Un ejemplo del cambio de contexto el
cual provoca contar una entrada de dos clientes como dos errores es la que sigue:
Cliente1-> Panaderia.clientesdentro++;
Cliente2-> Panaderia.clientesdentro++;
Cliente1-> if(Panaderia.clientedentro>=2)
y contar
a como un fallo
Cliente2-> if(Panaderia.clientedentro>=2)
y contar
a como otro fallo

<--Ahora vale Panaderia.clientesdentro=2


<--Dentro echar
a al cliente
<--Dentro echar
a al cliente2

Normalmente, solo uno de los dos entrara y lanzara la excepcion contando como fallo
individual.

2.

ExceptionClientes()

Dicha excepcion no hace nada, su papel consiste en aprovechar el hecho de que el


metodo Atender lanzara dicha excepcion y sera capturada en el cliente, el cual volcara la
traza de error y terminara la hebra una vez suelte el turno.
try {
dep.Atender(id);
}
catch (ExceptionClientes e)
{
e.printStackTrace();
} // cliente id es atendido por el dependiente

3.

Posibles errores y soluciones

Tal y como se comento en clase, el problema de la panadera consiste en resolver


la exclusion mutua de N >= 2 procesos. Esto lo hace a traves de ordenar el acceso a
la seccion crtica por turnos, ademas se utiliza una proteccion para asegurar que rara
vez 2 procesos seran atendidos simultaneamente. Para forzar los errores he comentado
la parte del codigo encargada de dormir la hebra mientras haya otra pidiendo turno,
cuyo objetivo era que solo se buscara la siguiente en ejecutar si ninguna estaba eligiendo
turno.
Funcion que busca al siguiente:
public static int siguiente() throws InterruptedException
{
int max = 0;
for(int i = 0; i < N; i++)
{
if(max< turno[i])
{
max = turno[i];
}
}
return max+1;
}

Posible cambio de contexto que provoque 2 con igual turno:


Cliente1->Encuentra que el m
aximo es 2, y se encuentra justo antes del return
Cliente2->Al no haberse llegado a hacer el return el m
aximo sigue siendo 2,
lo cual hace que tambien vea como m
aximo el 2
Cliente1->Asigna turno 3
Cliente2->Asigna turno 3

3.1.

Protecci
on meToca()

La solucion al problema de varios clientes con el mismo turno se gestiona en el metodo


meToca(), el cual se dedica a buscar cual sera el siguiente cliente atendido, y ante
igualdad de turnos escogera el de menor ndice.
public static boolean meToca(int id, int i)
{
if (turno[i]>0 && turno[i]<turno[id])
return false;
else if(turno[i]==turno[id] && i < id)
return false;
else return true;
}

3.2.

Protecci
on turnos

Con el objetivo de evitar que tal y como se vio en el punto anterior dos clientes pasen
ambos el metodo meToca() se creara un array protector el cual hara que solo se mire a
quien le toca en caso de que no se este pidiendo turno.
Panaderia.pidiendoTurno[id] = true;
Panaderia.turno[id] =Panaderia.siguiente();
Panaderia.pidiendoTurno[id] = false;
for (int i = 0; i < Panaderia.N; i++)
{
while(Panaderia.pidiendoTurno[i])
Thread.yield();
while(!Panaderia.meToca(id, i))
Thread.yield();
}

Cuando se quita dicha proteccion se puede ver el fallo visto, debido a varios clientes
siendo atendidos, tal y como se ve en la figura 1

Figura 1: Error tpico en esta situacion


Vemos como a dado un fallo justo al final del codigo ademas de otro que dio al
principio, por lo tanto el numero de fallos es igual a 2

You might also like