Beruflich Dokumente
Kultur Dokumente
Problemas clásicos
Rodolfo Baader
Problema:
Tenemos una serie de procesos Pi , i ∈ {1 . . . N} que se están
ejecutando en simultáneo (supongamos que tenemos N CPUs).
Cada proceso i tiene una sentencia si.
Queremos que en el sistema global se ejecuten s1, s2, . . . , sN.
¿De qué nos disfrazamos?
Podemos utilizar semáforos.
Listing 1: Inicialización
proc i n i t ()
{
f o r ( i= 0 ; i <N+1; i ++)
s e m a f o r o s [ i ]= new S e má f o r o ( 0 ) ;
f o r ( i= 0 ; i <N ; i ++)
f o r k P( i ) ;
semaforos [ 0 ] . s i g n a l ( ) ;
}
Listing 2: Proceso Pi
p r o c P( i )
{
s e m a n t= s e m a f o r o s [ i ] ;
s e m s i g= s e m a f o r o s [ i + 1 ] ;
sem ant . wait ( ) ;
s( i );
sem sig . s i g n a l ( ) ;
}
Listing 3: Inicialización
proc i n i t ()
{
e n b a r r e r a= 0 ; // Cant . de p r o c s en l a b a r r e r a .
mutex= new S e má f o r o ( 1 ) ; // P e r m i t o empezar de i n m e d i a t o .
b a r r e r a= new S e má f o r o ( 0 ) ;
f o r ( i= 0 ; i <N ; i ++) f o r k P( i ) ;
}
Listing 4: Proceso Pi
p r o c P( i )
{
a( i );
mutex . w a i t ( ) ; // A c c e s o a v a r . c o m p a r t i d a .
e n b a r r e r a ++;
b o o l t o d o s e n b a r r e r a= ( e n b a r r e r a==N ) ;
mutex . s i g n a l ( ) ;
i f ( todos en barrera )
// Todos e s t á n l i s t o s p a r a c o n t i n u a r . Que s i g a n .
barrera . signal ();
barrera . wait ( ) ;
b( i );
}
mutex . w a i t ( ) ; // A c c e s o a v a r . c o m p a r t i d a .
e n b a r r e r a ++;
b o o l t o d o s e n b a r r e r a= ( e n b a r r e r a==N ) ;
mutex . s i g n a l ( ) ;
i f ( todos en barrera )
// Todos e s t á n l i s t o s p a r a c o n t i n u a r . Que s i g a n .
barrera . signal ();
barrera . wait ( ) ;
barrera . signal ();
b( i );
}
mutex . w a i t ( ) ; // A c c e s o a v a r . c o m p a r t i d a .
e n b a r r e r a ++;
b o o l t o d o s e n b a r r e r a= ( e n b a r r e r a==N ) ;
mutex . s i g n a l ( ) ;
i f ( todos en barrera )
// Todos e s t á n l i s t o s p a r a c o n t i n u a r . Que s i g a n .
barrera . broadcast ( ) ;
else
barrera . wait ( ) ;
b( i );
}
Listing 7: Inicialización
proc i n i t ()
{
sem= new S e má f o r o ( k ) ;
f o r ( i= 0 ; i <N ; i ++) f o r k P( i ) ;
}
Listing 8: Proceso Pi
p r o c P( i )
{
sem . w a i t ( ) ;
sc ( i ) ;
sem . s i g n a l ( ) ;
}
Listing 9: Inicialización
proc i n i t ()
{
v a r i a b l e c o m p a r t i d a ; // É s t a e s l a que t o d o s s e d i s p u t a n .
mutex= new S e má f o r o ( 1 ) ;
a c c e s o e x c l u s i v o= new S e má f o r o ( 1 ) ;
i n t l e c t o r e s= 0 ;
f o r ( i= 0 ; i <N ; i ++) f o r k L e c t o r ( i ) ;
f o r ( i= 0 ; i <M; i ++) f o r k E s c r i t o r ( i ) ;
}
Leer ( compartida ) ;
mutex . w a i t ( ) ;
l e c t o r e s −−;
i f ( l e c t o r e s ==0)
// Soy e l ú l t i m o , d e j o que e n t r e n l o s escritores .
acceso exclusivo . signal ();
mutex . s i g n a l ( ) ;
}
func d e j a r t e n e d o r e s ( i )
{
tenedores [ izq ( i ) ] . signal ();
tenedores [ der ( i ) ] . s i g n a l ( ) ;
}
¿Está bien?
Esta solución garantiza EXCL, pero falla con DEAD.
¿Cómo rompemos el deadlock? Pensemos en las condiciones.
Tarea: pensar en soluciones para este problema. Buscar las ya
existentes.
El peluquero es sencillo:
proc Peluquero
while ( true )
{
a l g u n c l i e n t e . wait ( ) ;
pasar . s i g n a l ( ) ;
cortar pelo ();
}
// ”A v i s o ” que l l e g u é .
algun cliente . signal ();
// E s p e r o a que me d e j e n p a s a r .
pasar . wait ( ) ;
e n t r a r a c o r t a r s e e l p e l o ( ) ; // ¡Todo p a r a e s t o !
// S a l g o .
mutex . w a i t ( ) ;
c l i e n t e s −−;
mutex . s i g n a l ( ) ;