Monitores: ¿declaración de métodos?

Monitores: ¿declaración de métodos?

de Juan Manuel Rivara De Leon -
Número de respuestas: 3

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:


=====

monitor Monitor
    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?
En respuesta a Juan Manuel Rivara De Leon

Re: Monitores: ¿declaración de métodos?

de Jorge Merlino -
Es medio complicado de entender si mezclás procedimientos que están adentro y afuera del monitor. Nadie te obliga a comprimir el código que va adentro del monitor. El monitor puede empezar en la página 1 y tener el end en la página 5 si querés dejar espacio por las dudas.
Los monitores tienen un "programa principal" para inicializar que va adentro de un bloque begin-end sin nombre y que corre al principio de todo. No es necesario tener un procedimiento "init"
En tu código nadie hace signal de p0, p1, p2 y p3, quedan en deadlock los que hacen wait.
Sobre tu punto 2 la letra no dice nada de que eso esté mal. La idea de ordenar para evitar deadlock es correcta.