next up previous
Next: Spooler de impresora Up: Editor interactivo v2 Previous: Editor interactivo v2

Editor interactivo v2 (SOLUCIÓN)

 

En este sistema hay una serie de puntos clave que condicionan la estructura de procesos adoptada:

Estos requisitos obligan a separar en tareas diferentes el encolado de órdenes ---proceso Buffer---, la visualización ---proceso Visual---, y la edición propiamente dicha ---Ejecutor. La estructura de procesos, con un cuarto proceso que lee de teclado y produce las órdenes, se muestra en la figura.

Además, hay una serie de restricciones a la sincronización entre estos procesos:

Finalmente se ha llegado al esquema de canales de la figura, con el código simplificado de la otra página.

El proceso Teclado simplemente forma comandos a partir de la lectura del teclado y los envía a Buffer. Por otra parte, Buffer recibe peticiones de Ejecutor por Peticion y contesta con el primer comando de la cola o bien avisa que no hay comandos. Además, cuando llega el primer comando a la cola vacía, lo envía a Ejecutor sin esperar una petición previa. (Esto es una forma de evitar un bucle de espera activa.) El funcionamiento de Visual es pedir por PetVisu la parte visible del documento a Ejecutor. Para corresponder a ambos, ejecutor queda a la espera de un mensaje por PetVisu o por Trabajo después de quedarse vacío la cola de órdenes. Así se satisface el último requisito.

Naturalmente, no es la única solución posible.

A continuación se especifica el código CC-MODULA de las tareas.

TASK Buffer;
VAR Cola: TIPOCOLA;
    Comando: TIPOCOMANDO;
    Pet, EsperaOrden: BOOLEAN; 
BEGIN
  GetChannel(Comandos);
  GetChannel(Peticion);
  <<inicializar buffer>>
  esperaOrden:=TRUE; (* Empieza una racha de comandos *)
  LOOP
    SELECT
      WHEN esperaOrden, Receive(Comandos,Comando) DO 
        esperaOrden:=FALSE;
        Send(Trabajo,Comando);
      WHEN NOT(esperaOrden) AND NOT(Llena(Cola)),
        Receive(Comandos,Comando) DO
        Encolar(Comando,Cola);
      WHEN Vacia(Cola), Receive(Peticion,Pet) DO
        esperaOrden:=TRUE;
        Send(Fin,TRUE);
      WHEN NOT(Vacia(Cola)), Receive(Peticion,Pet) DO
        Send(Trabajo,Primero(Cola));
        QuitaPrimero(Cola)
    END 
  END
END Buffer;

TASK Ejecutor;
VAR Documento, Pantalla: TIPODOC;
    Comando: TIPOCOMANDO;
    FinComandos: BOOLEAN; 

BEGIN
  GetChannel(Trabajo);
  GetChannel(Fin);
  GetChannel(PetVisu);
  <<inicializar Documento, etc>>
  Receive(Trabajo,Comando);
  Ejecutar(Comando,Documento);
  FinComandos:=FALSE;
  DatosNuevos:=FALSE;
  LOOP
   SELECT
    WHEN Receive(Fin,FinComandos) DO
    WHEN Receive(Trabajo,Comando) DO
     Ejecutar(Comando);
     FinComandos:=FALSE;
     DatosNuevos:=TRUE;
     Send(Peticion,TRUE)
    WHEN FinComandos AND DatosNuevos, 
      Receive(PetVisu,Pet) DO
     ExtraePant(Documento,Pant);
     DatosNuevos:=FALSE;
     Send(Pantalla,Pant)
   END
  END
END Ejecutor;

TASK Visual;
VAR Pant: TIPODOC;

BEGIN
  GetChannel(Pantalla);
  LOOP
    Send(PetVisu,TRUE);
    Receive(Pantalla,Pant);
    Mostrar(Pant)
  END
END Visual;

TASK Teclado;
VAR Pulsaciones: TIPOTECLADO;
    Comando: TIPOCOMANDO; 

BEGIN
  LOOP
    LeerTeclado(Pulsaciones);
    Comando:=ConstruirComando(Pulsaciones);
    Send(Comandos,Comando)
  END
END Teclado;



next up previous
Next: Spooler de impresora Up: Editor interactivo v2 Previous: Editor interactivo v2



Angel Herranz Nieva
Thu Oct 31 20:12:45 MET 1996