next up previous
Next: About this document Up: Almacén automatizado Previous: Almacén automatizado

Almacén automatizado (SOLUCIÓN)

 

El problema del almacen automatizado describe una situación habitual en la gestión de recursos: se cuenta con un número limitado de recursos disponibles (6 piezas), que en algún momento pueden agotarse. Llegado a este punto los usuarios de los recursos (operarios) quedan a la espera de que se recargue el sistema con nuevos recursos, operación que se considera costosa. Como en este caso se tienen varios tipos de recursos (piezas A, B, C y D) y son solicitados de forma individual (de uno en uno), la gestión del sistema debe hacerse de tal forma que la recarga de un tipo de recurso, por ser como se ha dicho una operación costosa, no impida que puedan realizarse otra peticiones. Para ello, se delega en otro proceso la actividad de recargar (en este caso el Robot) que será el encargado de ir a por más piezas del tipo solicitado.

Finalmente, constatar que la gestión de las piezas puede realizarse de forma totalmente distribuida, puesto que los recursos (las piezas) son perfectamente distinguibles y su gestión independiente.

A continuación se presenta un programa en CcModula que resuelve el problema propuesto. Obsérvese que sólo ha sido necesario implementar un proceso Pieza, hacindo instancias a través de su parámetro de los diferentes tipos de piezas que se gestionan.

< C W >

MODULE AlmacenMecanico;

FROM CCWindow IMPORT Clear;

FROM CCInOut IMPORT WriteCard, WriteString, WriteLn, ReadCard, Retardo;

CONST
  NumOperarios = 10;

TYPE
  TipoPieza = (piezaA, piezaB, piezaC, piezaD);
  TipoSenyal =  CARDINAL;

VAR
  peticionPieza : ARRAY [piezaA .. piezaD] OF CHANNEL (* OF TipoSenyal *);
  recibePiezas  : ARRAY [piezaA .. piezaD] OF CHANNEL (* OF TipoSenyal *);
  avisarRobot   : CHANNEL;
  I             : CARDINAL;
  P             : TipoPieza;


TASK Pieza (tipo : TipoPieza);
VAR
  piezasQuedan :  CARDINAL;
  senyal       :  TipoSenyal;

BEGIN
  GetChannel (peticionPieza [tipo]);
  GetChannel (recibePiezas [tipo]);

  piezasQuedan := 6;

  LOOP
    SELECT
      WHEN (piezasQuedan > 0), Receive (peticionPieza [tipo], senyal) DO
        DEC (piezasQuedan);
        IF (piezasQuedan = 0) THEN
          Send (avisarRobot, tipo)
        END (* IF *)
      WHEN Receive (recibePiezas [tipo], senyal) DO
        piezasQuedan := 6;
    END (* SELECT *)
  END (* LOOP *)
END Pieza;

TASK Robot;
VAR
  tipo   : TipoPieza;
  senyal : TipoSenyal;

BEGIN
  GetChannel (avisarRobot);
  LOOP
    Receive (avisarRobot, tipo);
    << Ir al almacen a por una batea de piezas del tipo "tipo" >> 
    Send (recibePiezas[tipo], senyal);
  END (* LOOP *)
END Robot;

TASK Operario  (id : CARDINAL );
VAR
  tipo   : TipoPieza;
  senyal : TipoSenyal;
BEGIN
  LOOP
    << Determinar el "tipo" de pieza que se quiere >>
    Send (peticionPieza [tipo],  senyal); 
  END (* LOOP *)
END Operario;


BEGIN
  COBEGIN
    Robot;
    FORALL P:= piezaA TO piezaD DO
      Pieza (P)
    END; (* FORALL *)
    FORALL I:=1 TO NumOperarios DO
      Operario (I)
    END (* FORALL *)
  COEND
END AlmacenMecanico.

Una solución alternativa para implementar los procesos Pieza pasa por ``percatarse'' de que no es necesario mantener una instrucción SELECT y que puede resolverse con recepciones deterministas, como sigue:

TASK Pieza (tipo : TipoPieza);
VAR
   piezasQuedan :  CARDINAL;
   senyal       :  TipoSenyal;

BEGIN
  GetChannel (peticionPieza [tipo]);
  GetChannel (recibePiezas [tipo]);

  piezasQuedan := 6;

  LOOP
    Receive (peticionPieza [tipo], senyal);
    DEC (piezasQuedan);
    IF (piezasQuedan = 0) THEN
      Send (avisarRobot, tipo);
      Receive (recibePiezas [tipo], senyal) DO
      piezasQuedan := 6;
    END (* IF *)
  END (* LOOP *)
END Pieza;



Angel Herranz Nieva
Thu Oct 31 20:07:48 MET 1996