Documentos de Académico
Documentos de Profesional
Documentos de Cultura
CC Monitores
CC Monitores
Monitores
Curso 2016-2017
Pregunta
¿cómo implementamos un recurso compartido especificado?
class Parking {
private Monitor mutex ;
public Parking () {
mutex = new Monitor () ;
...
}
...
}
class Parking {
private Monitor mutex ; // Control mutex
private Monitor . Cond cond ; // Cola espera
private int nCoches ; // Memoria c o m p a r t i d a
public Parking () {
mutex = new Monitor () ;
cond = mutex . newCond () ;
}
public void entrar () {
public void salir () {
mutex . enter () ;
mutex . enter () ;
if ( nCoches >= CAP )
// CPRE = cierto
cond . await () ;
nCoches - -;
nCoches ++;
// nCoches < CAP
if ( nCoches < CAP &&
if ( cond . waiting >0)
cond . waiting >0)
cond . signal () ;
cond . signal () ;
mutex . leave () ;
mutex . leave () ;
}
}
class Parking {
private Monitor mutex ;
private Monitor . Cond cond ; C-TAD: Parking
private int nCoches ; // Tipo
Solución
NO! Si productores y consumidores fueran bloqueados en la misma
condition, al hacer el signal no sabrı́amos si se despierta un productor o
un consumidor
Cuando se completa el método almacenar sólo se puede despertar
un proceso consumidor → una condition para consumidores
Cuando se completa el método extraer sólo se puede despertar un
proceso productor → una condition para productores
class Almacen1Dato {
private Monitor mutex ; C-TAD: Almacen1Dato
private Monitor . Cond cAlmacenar ;
private Monitor . Cond cExtraer ;
private Object almacenado ;
OPERACIONES:
private boolean hayDato ; ACCION: almacenar:Tipo Dato[e]
public Almacen1Dato () { ACCION: extraer:Tipo Dato[s]
mutex = new Monitor () ;
cAlmacenar = mutex . newCond () ; DOMINIO
cExtraer = mutex . newCond () ; TIPO: Almacen1Dato = (Dato:Tipo Dato×
hayDato = false ; // Inicial
} HayDato : B)
public void almacenar ( Object e ) {
INVARIANTE: cierto
mutex . enter () ; // Ex . Mutua INICIAL: ¬self.HayDato
if ( hayDato ) // if (! CPRE )
cAlmacenar . await () ; CPRE: ¬self.HayDato
almacenado = e ; // POST almacenar(e)
hayDato = true ; // POST POST: self.Dato = e pre ∧ self.HayDato
if ( cExtraer . waiting () >0) // hayDato
cExtraer . signal () ;
CPRE: self.HayDato
extraer(s)
mutex . leave () ; // Ex . Mutua
} POST: s = selfpre .Dato ∧ ¬self.HayDato
// [ C O N TINUA ...]
C-TAD: Almacen1Dato
OPERACIONES:
...
ACCION: almacenar:Tipo Dato[e]
ACCION: extraer:Tipo Dato[s]
public Object extraer () {
mutex . enter () ; // Ex . Mutua DOMINIO
if (! hayDato ) // if (! CPRE ) TIPO: Almacen1Dato = (Dato : Tipo Dato×
cExtraer . await () ; HayDato : B)
hayDato = false ; // POST INVARIANTE: cierto
Object dato = almacenado ;
INICIAL: ¬self.HayDato
if ( cAlmacenar . waiting () >0) // ! hayDato
cAlmacenar . signal () ; CPRE: ¬self.HayDato
almacenar(d)
mutex . leave () ; // Ex . Mutua
POST: self.Dato = e pre ∧ self.HayDato
return dato ;
} CPRE: self.HayDato
}
extraer(s)
POST: s = selfpre .Dato ∧ ¬self.HayDato
1) CPRE = cierto
2) CPRE 6= cierto y la CPRE sólo depende del estado del
recurso
3) CPRE 6= cierto y la CPRE depende de parámetros de
entrada (y opcionalmente del estado del recurso)
1) CPRE = cierto
Pregunta
¿qué pasa si el conjunto de clases de equivalencia o de posibles valores de
los parámetros de entrada es enorme (o infinito)?
CPRE : id ∈ S
operacion(id)
POST : . . .