Anda di halaman 1dari 11

El barbero dormiln:

Problema planteado por Dijkstra en 1971


Una peluquera en la que hay un barbero, una silla de
peluquero y N sillas para que se sienten los clientes en espera,
si es que los hay.
Si no hay clientes presentes, el barbero se sienta en su silla
de peluquero y se duerme.
Cuando llega un cliente, ste debe despertar al barbero
dormiln.
Si llegan ms clientes mientras el barbero corta el cabello de
un cliente, se sientan (si hay sillas desocupadas) o salen de la
peluquera (si todas las sillas estn ocupadas).
Programar al barbero y los clientes.
Por lo que se ve, hay variables tipo bandera, que debe ser consultadas al iniciar un
proceso, esto es clasico en los sitemas operativos multiprogramacin.
El problema consiste en una barbera en la que trabaja un barbero que tiene un nico
silln de barbero y varias sillas para esperar. Cuando no hay clientes, el barbero se
sienta en una silla y se duerme. Cuando llega un nuevo cliente, ste o bien despierta al
barbero o si el barbero est afeitando a otro cliente se sienta en una silla (o se va si
todas las sillas estn ocupadas por clientes esperando). El problema consiste en realizar
la actividad del barbero sin que ocurran condiciones de carrera. La solucin implica el
uso de semforos y objetos de exclusin mutua para proteger la seccin critica .
Un semforo es una variable protegida (o tipo abstracto de datos) que constituye el
mtodo clsico para restringir o permitir el acceso a recursos compartidos (por ejemplo,
un recurso de almacenamiento) en un entorno de multiprocesamiento.

Fuente(s):
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
void graficar();
char SB, op; /*SB =1 indica ocupada, 0 vacia */
int SC[6], i, j, cc, orden, t1; /* las sillas llevaran el turno */

void main(){
textmode(C80);
textbackground(0);
for(i=0; i<6; i=i+1)SC[i]=0; /*formateo lugares clientes*/
SB=1;
cc=0;
orden=0;
do{
clrscr();
cout<<\n\n\n\tCODIGO DEL BARBERO DORMILON\n;
cout<<\n\t I= Ingreso de un nuevo cliente\n;
cout<<\n\t T= Terminar la atencion a un cliente\n;
cout<<\n\t F= Finalizar el programa\n;
graficar();
op=getch();
if(op==i || op==I')
{
cc=0;
if(SB==0)cout<<\n\tBARBERO TRABAJANDO;
else cout<<\n\tBARBERO EN SU SILLA, DURMIENDO;
if(SB==1){SB=0; cout<<\n\nSr Cliente, TIENE QUE DESPERTAR AL
BARBERO; }
else{
for(i=0; i<6; i=i+1){
if(SC[i]==0){cout<<\nSr Cliente, Pase Ud y ubiquese en la silla: <<i+1;
orden=i; break;}
}/*fin del for*/
/*Se verifica lugares ocupados*/
for(i=0; i<6; i=i+1)if(SC[i]!=0)cc=cc+1;
if(cc<6)SC[orden]=cc+1; /*se le asigna el proximo turno*/
}/*del else por barbero dormido*/
cout<<\nSr Cliente: Vea que hay: <<cc<< clientes en espera;
if(cc>5) cout<<\nEstimado Cliente, en este momento no hay lugar para Ud, vuelva

mas tarde\no pruebe en otra barberia;


getch();
}/*del if op ingreso del cliente */
if(op==t || op==T')
{
t1=7;
/*se elige el turno mas bajo !=0 */
for(i=0; i<6; i=i+1) if(SC[i]<t1 && SC[i]!=0){t1 = SC[i];orden=i;}
for(i=0; i<6; i=i+1) if(SC[i]==t1)
cout<<\nEL Cliente ubicado en la silla: <<orden+1<< Sigue para atencion: ;
/* actualiza los turnos */
for(i=0; i<6; i=i+1) if(SC[i]!=0) SC[i] = SC[i]-1;
if(t1==7){
SB=1;
cout<<\n\tNO HAY MAS CLIENTES; EL BARBERO SE VA A SU SILLA A
DORMIR;
}
getch();
}/*del if op*/
}while (op!=f'&& op!=F');
}/*del main*/
void graficar()
{ /*Este codigo solo corre en turbo c++ de Borland*/
textbackground(11);textcolor(1);
gotoxy(20,14);cprintf( GRAFICO DEL BARBERO DORMILON );
textbackground(2);textcolor(15);
gotoxy(20,15);cprintf( );
gotoxy(20,16);cprintf( [ ] Silla Barbero);
if(SB==1){gotoxy(24,16);cprintf( Zzzz..);}
else {gotoxy(24,16);cprintf( ]WORKING!!!);}

gotoxy(20,17);cprintf( );
gotoxy(20,18);cprintf(Sillas Clientes:[ ][ ][ ][ ][ ][ ]);
gotoxy(20,19);cprintf( Turnos: );
gotoxy(20,20);cprintf( Ingrese Opcion: );
for(i=0; i<6; i=i+1){
if(SC[i]!=0){
textbackground(6);
gotoxy(37+(i*3),18); cprintf( );
textbackground(2);
gotoxy(37+(i*3),19); cprintf(%i, SC[i]);
}
else { gotoxy(28+(i*4),33); cprintf( ); }
}
textbackground(0);
gotoxy(20,50);
}
Filosofos Comensales
Cinco Filsofos se sientan alrededor de una mesa y pasan su vida cenando y
pensando. Cada filsofo tiene un plato de fideos y un tenedor a la izquierda de
su plato. Para comer los fideos son necesarios dos tenedores y cada filsofo
slo puede tomar los que estn a su izquierda y derecha. Si cualquier filsofo
coge un tenedor y el otro est ocupado, se quedar esperando, con el tenedor
en la mano, hasta que pueda coger el otro tenedor, para luego empezar a
comer.
Si dos filsofos adyacentes intentan tomar el mismo tenedor a una vez, se produce
una condicin de carrera: ambos compiten por tomar el mismo tenedor, y uno de ellos
se queda sin comer.
Si todos los filsofos cogen el tenedor que est a su derecha al mismo tiempo, entonces
todos se quedarn esperando eternamente, porque alguien debe liberar el tenedor que les
falta. Nadie lo har porque todos se encuentran en la misma situacin (esperando que

alguno deje sus tenedores). Entonces los filsofos se morirn de hambre. Este bloqueo
mutuo se denomina interbloqueo o deadlock.
El problema consiste en encontrar un algoritmo que permita que los filsofos nunca se
mueran de hambre.
Algunas Posibles Soluciones

Por turno cclico

Se empieza por un filsofo, que si quiere puede comer y despus pasa su turno al de la
derecha. Cada filsofo slo puede comer en su turno. Problema: si el nmero de
filsofos es muy alto, uno puede morir de hambre antes de su turno.

Varios turnos

Se establecen varios turnos. Para hacerlo ms claro supongamos que cada filsofo que
puede comer (es su turno) tiene una ficha que despus pasa a la derecha. Si por ejemplo
hay 7 comensales podemos poner 3 fichas en posiciones alternas (entre dos de las fichas
quedaran dos filsofos).
Se establecen turnos de tiempo fijo. Por ejemplo cada 5 minutos se pasan las fichas (y
los turnos) a la derecha.
En base al tiempo que suelen tardar los filsofos en comer y en volver a tener hambre,
el tiempo de turno establecido puede hacer que sea peor solucin que la anterior. Si el
tiempo de turno se aproxima al tiempo medio que tarda un filsofo en comer esta
variante da muy buenos resultados. Si adems el tiempo medio de comer es similar al
tiempo medio en volver a tener hambre la solucin se aproxima al ptimo.

Colas de tenedores

Cuando un filsofo quiere comer se pone en la cola de los dos tenedores que necesita.
Cuando un tenedor est libre lo toma. Cuando toma los dos tenedores, come y deja libre
los tenedores.
Visto desde el otro lado, cada tenedor slo puede tener dos filsofos en cola, siempre
los mismos.
Esto crea el problema comentado de que si todos quieren comer a la vez y todos
empiezan tomando el tenedor de su derecha se bloquea el sistema (deadlock).

Resolucin de conflictos en colas de tenedores

Cada vez que un filsofo tiene un tenedor espera un tiempo aleatorio para conseguir el
segundo tenedor. Si en ese tiempo no queda libre el segundo tenedor, suelta el que tiene
y vuelve a ponerse en cola para sus dos tenedores.
Si un filsofo A suelta un tenedor (porque ha comido o porque ha esperado demasiado
tiempo con el tenedor en la mano) pero todava desea comer, vuelve a ponerse en

cola para ese tenedor. Si el filsofo adyacente B est ya en esa cola de tenedor (tiene
hambre) lo toma y si no vuelve a cogerlo A.
Es importante que el tiempo de espera sea aleatorio o se mantendr el bloqueo del
sistema.

El portero del comedor

Se indica a los filsofos que abandonen la mesa cuando no tengan hambre y que no
regresen a ella hasta que vuelvan a estar hambrientos (cada filsofo siempre se sienta en
la misma silla). La misin del portero es controlar el nmero de filsofos en la sala,
limitando su nmero a n-1, pues si hay n-1 comensales seguro que al menos uno puede
comer con los dos tenedores.
Solucin
Por Semforos
/* Solucion a la cena de los filosofos

mediante semaforos.

*/

#define TRUE1

#define N5

#define LEFT(x)(((x)-1)%N)

#define RIGHT(X)(((X)+1)%N)

typedef struct

int value;

/* Lista de procesos.

*/

semaphore;

typedef enum

THINKING, HUNGRY, EATING

status;

/* Estado de cada filosofo.

*/

status estado[N];

/* Semaforo para exclusion mutua.

*/

semaphore mutex,

/* Semaforo para bloquear los filosofos adyacentes.

s[N];

main ()

extern status estado[N];

extern semaphore mutex, s[N];

int i, sw = 1;

void Philosopher (int);

*/

/* Inicializamos los semaforos.

*/

InitSemaphore (mutex, 1);

for (i = 0; i < N; i++)

InitSemaphore (s[i], 0);

/* Inicializamos los estados.

*/

for (i = 0; i < N; i++)

estado[i] = THINKING;

/* Inicializamos los filosofos.

*/

for (i = 0; (i < N) && (sw); i++)

if (!(sw = fork ()))

Philosopher (i);

void

Philosopher (int i)

void think (), eat (), TakeForks (int), PutForks (int);

while (TRUE)

think ();

/* Obtiene dos tenedores o se bloquea.

TakeForks (i);

eat ();

PutForks (i);

void

TakeForks (int i)

void test (int);

extern semaphore mutex, s[N];

extern status estado[N];

/* Acceso a seccion critica.

*/

wait (mutex);

estado[i] = HUNGRY;

/* Intenta tomar los dos tenedores.

test (i);

*/

*/

signal (mutex);

/* Se bloquea si no consiguio los tenedores.

*/

wait (s[i]);

void

PutForks (int i)

void test (int);

extern semaphore mutex;

extern status estado[N];

/* Acceso a seccion critica.

*/

wait (mutex);

estado[i] = THINKING;

/* Comprueba si el vecino izquierdo puede comer ahora.

*/

test (LEFT (i));

/* Comprueba si el vecino derecho puede comer ahora.

test (RIGHT (i));

signal (mutex);

*/

void

test (int i)

extern semaphore s[N];

extern status estado[N];

if (estado[i] == HUNGRY && estado[LEFT (i)] != EATING &&

estado[RIGHT (i)] != EATING)

estado[i] = EATING;

signal (s[i]);