[Práctico 5][Ejer 4]

[Práctico 5][Ejer 4]

de Andres Bello Ureta -
Número de respuestas: 2
Hola, plantee una solución para cada parte del ejercicio y me gustaría saber si estan bien o me pase por alto algún detalle, los dejo adjuntos dos txt junto con la letra. Gracias.
Saludos,
   Andrés.
En respuesta a Andres Bello Ureta

Re: [Práctico 5][Ejer 4]

de Pablo Enrique Gonzalez Inthamoussu -

Buen día Andrés, 

   Estuve viendo la solución de la parte a, y me parece que se te presenta el siguiente problema, se hace P(com_llenar), pero nunca se hace el V(com_llenar), entonces me parece que se va poder llenar solo una botella porque en el prox ciclo el semaforo va a estar en 0, y la máquina va quedar bloqueada. Lo mismo para com_tapar.
   Por otro lado, el avanzar cinta se invoca una sola vez, por lo que la cinta se desplaza una sola vez, eventualmente podría no llenarse ninguna botella. Capaz que el avanzar hace un bucle con avanzo_cinta.

   Con respecto a la parte a, creo  que hay que pensarlo algo parecido al problema del productor-consumidor, donde el productor es la máquina de llenar y el consumidor la maquina de tapar.

   la solución que se me ocurrió es esta:

  • una variable global que cuente las botellas que están llenas, cant_botellas_llenas
  • un semáforo binario, para la modificación de la variable anterior
  • un semáforo genérico que se libera cuando se llena una botella, (incrementando en 1, la cantidad de procesos que van a poder antender)
  • como la cinta avanza a pasos pequeños, asumir que no es necesario hacer un stop de la cinta para llenar y/o tapar la cinta

Program algarroba_coca();

var
    mutex: semaforo; (* semaforo binario *)
    s_botella_llena: semaforo; 

procedure llenar_botella()
begin
    while(true)do
    begin
       if (puedo_llenar) then
       begin
              llenar_botella(); 
              P(mutex);
              cant_botellas_llenas:= cant_botellas_llenas+1;
              V(mutex);
              V(s_botella_llena); (* libera el  semaforo (incrementando la cant de procesos que van a poder hacer el P) para que el P(s_botella_llena) siga de largo del proceso de tapar*)
      end; (* if *)
    end; (* while *)
end;

procedure tapar_botella()

var puedo_tapar: boolean;

begin
     while(true) do
     begin
        puedo_tapar:=false;
        P(s_botella_llena);
        P(mutex);
       
 if (cant_botellas_llenas > 0) then
        begin
             puedo_tapar:=true;
        end;
        V(mutex); 
(* no importa si la variable se modifica mientras se tapa la botella, ya que importa que la cantidad sea mayor a 0 y el llenado solo incrementa*)
        if (puedo_tapar) then
        begin

            tapar_botella();
            
P(mutex); (* se ejecuta dos veces el mutex , para que el llenado pueda incrementar la variable mientras la máquina está tapando*)
            cant_botellas_llenas := cant_botellas_llenas - 1;
            V(mutex);
        end;
    end; (* del while *)

end;

(* la cinta como avanza a pasos muy chicos se asume que no es necesario hacer un stop de  la cinta al llenar y/o tapar la botella *) 
procedure avanzar()
begin
     while(true)do
         avanzar_cinta();
end;

begin

     init(mutex, 1); (* el primero que va hacer el P  es el llenado *)
     init(
s_botella_llena, 0); (* de entrada bloquea al tapar botellas *)
     cant_botellas_llenas := 0;
     cobegin
         tapar_botella();llenar_botella();avanzar();
     coend;
end;

Al igual que vos, no estoy seguro si esta es una solución correcta, ni si es la más óptima, jeje,
Saludos
Pablo Gonzalez.

En respuesta a Pablo Enrique Gonzalez Inthamoussu

Re: [Práctico 5][Ejer 4]

de Andres Bello Ureta -
No me dí cuenta cuando subí el .txt me falto escribir el procedimiento avanzar(), este hace:
procedure avanzar(){
   P(s)
   P(s)
   avanzo();
   V(com_tapar);
   V(com_llenar);
}

La idea es que luego de avanzar la cinta el procedimiento avanzar()  habilite a poder tapar y llenar otras botellas, haciendo V(com_tapar) y V(com_llenar).

El tema de que el avanzar se ejecuta una vez tenes razon, deberia poner todo lo que esta en cobegin coend dentro de un loop infino.

Con respecto a tu solución:
(* la cinta como avanza a pasos muy chicos se asume que no es necesario hacer un stop de  la cinta al llenar y/o tapar la botella *) 
procedure avanzar()
begin
     while(true)do
         avanzar_cinta();
end;

Haciendo simplemente avanzar_cinta() no estas esperando que la bottela se llene/tape, si le sacas el cpu a mientras se esta llenando y se lo da a avanzar() podrias avanzar sin nada que te tranque, me explico?, para mi tenes que implementar algo de que antes de avanzar se fije si lleno o tapo.