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:

- La recepción de nuevas órdenes se ha de hacer concurrentemente con la modificación del documento.

- Se puede visualizar también al mismo tiempo que se modifica el documento y se reciben órdenes.

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:

- La visualización sólo se produce cuando se queda vacía la cola de órdenes.

- El proceso Ejecutor deberá esperar a que se le avise de que hay nuevas órdenes, en vez de preguntar continuamente. Análogamente, el visualizador no debe visualizar repetidamente un documento mientras no sufra cambios.

- Además, es deseable que Ejecutor no deje de procesar órdenes por culpa de un retraso del visualizador.

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: Spooler de impresora Up: Editor interactivo v2 Previous: Editor interactivo v2