[Practico 6][Ejercicio 10]

[Practico 6][Ejercicio 10]

de Rodrigo Gaston Nicodella Falero -
Número de respuestas: 3

Hola, tengo el siguiente codigo del task Baño y me genera una duda porque la letra pide que el reponedor y el de limpieza puedan existir dentro de cada cada baño. Para respetar la prioridad utilizo el llegoMantenimiento´Count > 0 (porque lo ejecutan ambos)

El caso que me genera duda es cuando tengo personas utilizando el baño y se ejecuta llegoMantenimiento pero cantPersonas no es 0, tengo entendido que el select evalua todas las guardas y descarta las falsas, por ende solo serian verdaderas: 

*cantPersonasManteniendo >0 

*cantPersonas > 0

  Que pasa con Reponedor y Limpiador si la primer guarda es falsa? se bloquea en algun accept de las guardas verdaderas?

otra pregunta si este codigo esta mal? como seria la solución correcta? no me doy cuenta como bloquear a los de mantenimiento hasta que no existan personas en el baño (cantPersonas == 0).

task type Baño is

    entry entrar

    entry salir

    entry llegoMantenimiento

    entry salirMantenimiento

task body Baño is

    Integer cantPersonas

    Integer nroBaño

    Integer cantPersonasDesdeUltimaLimpieza

    Integer cantPersonasManteniendo

begin  

    cantPersonasDesdeUltimaLimpieza = 0

    cantPersonas = 0

    cantPersonasManteniendo = 0

    accept numero(in : Integer nro)

        nroBaño = nro

    loop

        select

            when llegoMantenimiento´count > 0 and cantPersonas == 0 and cantPersonasManteniendo < 2

                accept llegoMantenimiento(in : Boolean tipo) 

                    cantPersonasManteniendo ++

                    if tipo

                        limpiar(cantPersonasDesdeUltimaLimpieza)

                        cantPersonasDesdeUltimaLimpieza = 0 

                    else

                        reponer()           

        or

            when cantPersonasManteniendo > 0

                accept salirMantenimiento

                    cantPersonasManteniendo --

        or      

            when llegoMantenimiento´count == 0 and cantPersonas < 4

                    and cantPersonasManteniendo == 0

                accept entrar

                    cantPersonas ++

                    cantPersonasDesdeUltimaLimpieza ++

        or

            when cantPersonas > 0

                accept salir

                    cantPersonas --


    endloop

end


En respuesta a Rodrigo Gaston Nicodella Falero

Re: [Practico 6][Ejercicio 10]

de Federico Rivero -
Hola Rodrigo!

Es difícil contestar las preguntas específicas porque el código así como está no funciona muy bien. La clausula 'when llegoMantenimiento´count > 0' lo que hace es intentar aceptar esa entry solo si el limpiador o reponedor están invocándola. Es decir, si al momento de ejecutar el select ninguno de los dos están invocando  baño.llegoMantenimiento(), entonces esa entry no se va a aceptar hasta la próxima vez que se evalúe el select. Eso es un problema porque si por ejemplo al momento de ejecutar el select no hay ni personas adentro del baño, ni limpiador o reponedor en el baño o intentando acceder, entonces esa entry no se va a aceptar, y si el limpiador llega momentos después, va a tener que esperar a que llegue una persona, salga y recién ahí en la nueva ejecución del select se va a aceptar la entry call realizada por el limpiador.

En resumen, esa cláusula when no debería ir.

Por último, acordate que si en algún momento todas las entries del select están cerradas entonces el task aborta. Te lo digo porque hay lógica complicada en los when de tu programa y no me queda claro que siempre haya alguna abierta, revisalo por favor.

Saludos,
Federico
En respuesta a Federico Rivero

Re: [Practico 6][Ejercicio 10]

de Rodrigo Gaston Nicodella Falero -
Bien, creo que entendi hasta cierta parte.
* Lo primero seria sacarle la guarda al llegoMantenimiento ya que asi en cualquier momento puede ser invocado, con eso ya logras prioridad?
Con esto me surge la misma pregunta que nombre mas arriba, que pasa o como controlo que si alguien de mantenimiento ya invoco el encuentro accept llegoMantenimiento(in : Boolean tipo) y tengo personas dentro del baño? no me doy cuenta como bloquear al de mantenimiento para que no siga ejecutando.
Igualmente esta duda va mas allá de este problema.

Gracias!
En respuesta a Rodrigo Gaston Nicodella Falero

Re: [Practico 6][Ejercicio 10]

de Federico Rivero -
Hola!

La condición 'when cantPersonas == 0' está bien! Porque ahí si hay alguien adentro del baño no dejás pasar a la persona de mantenimiento. Lo que está mal es la primer parte de la condición: 'when llegoMantenimiento'count > 0', porque eso tiene el efecto que expliqué en el primer mensaje.

La prioridad está bien implementada y eso se controla en la guarda del accept entrar, donde escribiste 'when llegoMantenimiento´count == 0'. Eso funciona correctamente poque el flujo es: 1) personas entran al baño 2) llega el limpiador y se tranca porque su entry call está cerrada con la condición 'when cantPersonas == 0' 3) las personas adicionales que llegan al baño también se trancan porque el accept entrar está cerrada por la guarda 'when llegoMantenimiento´count == 0'. 

Luego de eso, el flujo va a ser que 1) las personas salen del baño 2) cuando no quede ninguno en el baño se va a cumplir la condición 'when cantPersonas == 0' y el limpiador va a poder entrar 3) cuando el limpiador salga del baño va a dejar entrar a personas adicionales. Es decir, funciona bien :)

Saludos,
Federico