next up previous
Next: El peluquero dormilón Up: Manejadores y servidores Previous: Manejadores y servidores

Manejadores y servidores de disco (SOLUCIÓN)

 

En este problema se propone buscar una solución que gestione las operaciones, tanto de lectura como de escritura, que realizan unos usuarios sobre la información almacenada en varios discos independientes. Como se proponía en el gráfico del enunciado, cada disco va a tener asociados: un proceso Manejador (manipulador directo) del disco y un proceso Servidor que atiende y gestiona todas las peticiones que se hagan sobre él. Todos los discos son similares, y se diferencian porque cada uno tiene un identificador diferente. Por tanto, la solución del problema sólo requiere la implementación de tres tipos de tareas: Manejador, Servidor y Cliente.

  1. Grafo de procesos.

  2. Descripción de los procesos Manejador y Servidor.

    Obsérvese la función que desempeñan las operaciones de las colas de peticiones, en la implementación de la sincronización en el proceso servidor. Por otro lado, resulta relevante el hecho de que el proceso manejador desempeñe una actitud activa en la ejecución, no teniendo que esperar a que exista una petición de operación del Servidor, sino adelantándose a ésta e indicando su situación de ``preparado'' para operar sobre el disco.

    MODULE  Discos;
    FROM COLAS IMPORT TipoCola,  (* TipoPeticion *)
                      CreaVacia,
                      Llena,
                      Vacia,
                      Insertar,
                      Borrar,
                      Primero;
    
    CONST  NumDiscos = 3;
           NumClientes = 5;
    
    TYPE  TipoDato = INTEGER;
    
    TYPE  TipoPeticion = RECORD
                           sector: INTEGER;
                           CASE  esLectura: BOOLEAN  OF
                             TRUE:  cliente: INTEGER |
                             FALSE: dato: TipoDato
                           END
                         END;
    
    TYPE  RespuestaLectura = RECORD
                               dato: TipoDato;
                               cliente: INTEGER
                             END;
    
    VAR  datoLeido: ARRAY [1..NumClientes] OF CHANNEL;   (* cliente *)
    
    VAR  pedirOperacion,
         pedirOrden,
         retornoLectura,     (* servidor *)
         orden:                                          (* disco *)
         ARRAY [1..NumDiscos] OF CHANNEL;
    
    TASK  Manejador (i: INTEGER);
      VAR  peticion: TipoPeticion;
           respuesta: RespuestaLectura;
    BEGIN
      (*... iniciar disco ...*)
      LOOP
        Send(pedirOrden[i], TRUE);
        Receive(orden[i], peticion);
        IF  peticion.esLectura  THEN
          (*... Leer 'respuesta.dato' del sector 'peticion.sector' ...*)
          respuesta.cliente := peticion.cliente;
          Send(retornoLectura[i], respuesta)
        ELSE
          (*... Escribir 'peticion.dato' en 'peticion.sector' ...*)
        END
      END
    END Manejador;
    
    
    TASK  Servidor(i: INTEGER);
      VAR  cola:  TipoCola;
           x: BOOLEAN;
           peticion: TipoPeticion;
           respuesta: RespuestaLectura;
    BEGIN
      GetChannel(pedirOperacion[i]);
      GetChannel(pedirOrden[i]);
      GetChannel(retornoLectura);
      CrearVacia (cola);
      LOOP
        SELECT
          WHEN  NOT Llena(cola), Receive(pedirOperacion[i], peticion)  DO
            Insertar(cola, peticion)
          WHEN  NOT Vacia(cola), Receive(pedirOrden[i], x) DO
            Primero (cola, peticion);
            Borrar (cola);
            Send(orden[i], peticion)
          WHEN  TRUE, Receive(retornoLectura[i], respuesta)  DO
            Send(datoLeido[respuesta.cliente], respuesta.dato)
        END
      END
    END Servidor;
    

  3. Descripción de los procesos clientes.

    La actividad de los clientes está sujeta a la ejecución de una de las dos operaciones (Leer o Escribir) para actuar sobre el disco. Dichas operaciones son, precisamente, los ``servicios'' que ofrece cada servidor de disco a los clientes. Junto a todo esto, la implementación de las operaciones debe hacerse bajo la forma de procedimientos con unas cabeceras determinadas.

    Las operaciones de lectura y escritura son diferentes en cuanto que lo es el sentido de la comunicación que producen. Así, mientras que la operación de escritura no implica la espera del proceso cliente (una vez se haya notificado al servidor la petición no hay que esperar a que se escriba realmente), para el caso de la lectura esto no es así, y el proceso cliente debe esperar a recibir los datos que haya solicitado. Lo anterior tiene una trascendencia mayor que la esperada para el caso de las lecturas:

    ... para que los datos puedan ser remitidos desde el servidor al cliente, éste previamente debe haberle indicado cuál es el canal por el que deberá enviarle dichos datos.

    Como el enunciado obligaba a la utilización de unas cabeceras de procedimientos en las cuales no se hace ninguna mención al canal de recepción, la solución pasa por incluir, cuando la operación es de lectura, el canal de recepción dentro del mensaje enviado al servidor.

    TASK  Cliente(i: INTEGER);
    VAR
        disco,
        sector : CARDINAL;
        dato   : TipoDato;
    
      PROCEDURE  Leer(disco, sector: INTEGER; VAR dato: TipoDato);
        VAR  lectura: PeticionLectura;
      BEGIN
        lectura.sector := sector;
        lectura.cliente := i;
        Send(pedirLectura[disco], lectura);
        Receive(datoLeido[i], dato)
      END Leer;
    
      PROCEDURE  Escribir(disco, sector: INTEGER; dato: TipoDato);
        VAR  escritura: PeticionEscritura;
      BEGIN
        escritura.sector := sector;
        escritura.dato := dato;
        Send(pedirEscritura[disco], escritura)
      END Escribir;
    
    BEGIN
      GetChannel(datoLeido[i]);
      LOOP
         (* .. Operaciones de lectura y/o escritura .. *)
      END
    END Cliente;
    
    VAR  k: INTEGER;
    
    BEGIN
      COBEGIN
        FORALL k := 1 TO NumDiscos  DO
          Manejador(k);
          Servidor(k)
        END;
        FORALL k := 1 TO NumClientes  DO
          Cliente(k)
        END;
      COEND
    END Discos.
    



next up previous
Next: El peluquero dormilón Up: Manejadores y servidores Previous: Manejadores y servidores



Angel Herranz Nieva
Thu Oct 31 20:08:57 MET 1996