Buenas.
Quería consultar sobre la posibilidad de declarar los métodos públicos del monitor previo a su implementación.
La motivación es que durante la resolución de un ejercicio puede ser necesario agregar locks o controles adicionales. Si cada método del monitor debe ser implementado de manera contigua, entonces deberíamos borrar todo lo desarrollado posteriormente para agregar los métodos nuevos del monitor.
Mi propuesta, es, entonces, declarar los métodos que pertenecen al monitor para luego tener flexibilidad de implementarlos en cualquier parte del ejercicio.
Ejemplo con el ejercicio 3 del práctico 5:
=====
int: salaempleados, puertaempleados
bool: a0, a1, a2, a3, salacerrada
condition: p0, p1, p2, p3, salavacia, salaabierta
def init()
def entrar()
def salir()
def adquirir(int: nro)
def liberar(int: nro)
def cerrar()
def abrir()
end
def empleado(int: nro):
var
int: p1, p2, f1, f2
begin
p1 = nro
p2 = (nro +1) mod 4
if p1 < p2
f1 = p1
f2 = p2
else
f1 = p2
f2 = p1
end
while true:
Monitor.entrar()
Monitor.adquirir(f1)
Monitor.adquirir(f2)
realizar_controles(f1, f2)
Monitor.liberar(f1)
Monitor.liberar(f2)
Monitor.salir()
otras_tareas()
end
end
def init():
begin
a0 = false
a1 = false
a2 = false
a3 = false
salacerrada = false
salaempleados = 0
puertaempleados = 0
end
def entrar():
var
begin
if salacerrada:
puertaempleados = puertaempleados +1
salaabierta.wait()
end
salaempleados = salaempleados +1
end
def salir():
var
begin
salaempleados = salaempleados -1
if salaempleados == 0:
salavacia.signal()
end
end
def adquirir(int: nro):
var
begin
if nro == 0:
if a0 == true
p0.wait()
a0 = true
elif nro == 1:
if a1 == true
p1.wait()
a1 = true
elif nro == 2:
if a2 == true
p2.wait()
a2 = true
else:
if a3 == true
p3.wait()
a3 = true
end
end
def liberar(int: nro)
var
begin
if nro == 0:
a0 = false
elif nro == 1:
a1 = false
elif nro == 2:
a2 = false
else:
a3 = false
end
end
def supervisor():
var
int: p1, p2, f1, f2
bool: verif
begin
while True:
p1 = que_verif()
p2 = que_verif()
if p1 < p2:
f1 = p1
f2 = p2
else:
f1 = p2
f2 = p1
end
Monitor.adquirir(f1)
Monitor.adquirir(f2)
verif = verif_paneles(f1, f2)
Monitor.liberar(f2)
Monitor.liberar(f1)
Monitor.liberar(f1)
if verif == false:
Monitor.cerrar()
reparar_paneles()
Monitor.abrir()
end
otras_tareas()
end
end
def cerrar()
var
begin
salacerrada = true
if salaempleados > 0
salavacia.wait()
end
def abrir()
var
begin
salaabierta = true
for i in 1..puertaempleados:
salaabierta.signal()
end
puertaempleados = 0
end
def main():
var
begin
cobegin
empleado(0)
empleado(1)
empleado(2)
empleado(3)
supervisor()
coend
end
=====
También agrego un par de observaciones sobre la solución:
1. En principio podría haberse utilizado arreglos para almacenar los paneles en lugar de variables separados y así hacerlo más corto, dejé otra consultra al respecto aquí: https://eva.fing.edu.uy/mod/forum/discuss.php?d=290385
2. En esta solución en principio sería posible que el supervisor le permita al empleado usar una única vez un par de paneles defectuosos si el empleado ya había ingresado a la sala para utilizarlos. No sé si esto viola las restricciones del problema (en principio si el supervisor controla cada tanto tiempo y no antes de cada uso parece que no es catastrófico que se utilicen paneles defectuosos brevemente).
3. Se adquieren en orden creciente los paneles para evitar deadlocks. Entiendo que la prevención de deadlock es una parte del ejercicio, ya que se deben adquirir varios recursos compartidos para completar la tarea. ¿Supongo que esta enfoque es correcto?