Solución de Lectores-Escritores usando Monitores

Prerrequisito: Sincronización de procesos , Monitores , Lectores-escritores Problema
Teniendo en cuenta una base de datos compartida, nuestros objetivos son:

  • Los lectores pueden acceder a la base de datos solo cuando no hay escritores.
  • Los escritores pueden acceder a la base de datos solo cuando no hay lectores o escritores.
  • Solo un subproceso puede manipular las variables de estado a la vez.

Estructura básica de una solución –

Reader()
   Wait until no writers
   Access database
   Check out – wake up a waiting writer
Writer()
   Wait until no active readers or writers
   Access database
   Check out – wake up waiting readers or writer

–Ahora supongamos que un escritor está activo y ahora aparece una mezcla de lectores y escritores.
¿Quién debería entrar después?
–O supongamos que un escritor está esperando y sigue apareciendo un flujo interminable de lectores.
¿Sería justo que se activaran?
Así que implementaremos una especie de forma de equidad de ida y vuelta:

  • Una vez que un lector está esperando, los lectores entrarán a continuación.
  • Si un escritor está esperando, un escritor entrará a continuación.

Implementación de la solución usando monitores:-

  1. Los métodos deben ejecutarse con exclusión mutua, es decir, en cada momento, como máximo un subproceso puede estar ejecutando cualquiera de sus métodos.
  2. Los monitores también proporcionan un mecanismo para que los subprocesos renuncien temporalmente al acceso exclusivo, a fin de esperar a que se cumpla alguna condición, antes de recuperar el acceso exclusivo y reanudar su tarea.
  3. Los monitores también tienen un mecanismo para señalar a otros subprocesos que se han cumplido tales condiciones.
  4. Entonces, en esta implementación, solo la exclusión mutua no es suficiente. Los subprocesos que intentan una operación pueden necesitar esperar hasta que alguna afirmación P sea cierta.
  5. Mientras un subproceso espera una variable de condición, no se considera que ese subproceso ocupe el monitor, por lo que otros subprocesos pueden ingresar al monitor para cambiar el estado del mismo.

Código –

// STATE VARIABLES
// Number of active readers; initially = 0
int NReaders = 0;
  
// Number of waiting readers; initially = 0
int WaitingReaders = 0;
  
// Number of active writers; initially = 0
int NWriters = 0;
  
// Number of waiting writers; initially = 0
int WaitingWriters = 0;
  
Condition canRead = NULL;
Condition canWrite = NULL;
  
Void BeginWrite()
{
  
    // A writer can enter if there are no other
    // active writers and no readers are waiting
    if (NWriters == 1 || NReaders > 0) {
  
        ++WaitingWriters;
        wait(CanWrite);
        --WaitingWriters;
    }
  
    NWriters = 1;
}
  
Void EndWrite()
{
  
    NWriters = 0;
  
    // Checks to see if any readers are waiting
    if (WaitingReaders)
  
        Signal(CanRead);
  
    else
  
        Signal(CanWrite);
}
  
Void BeginRead()
{
  
    // A reader can enter if there are no writers
    // active or waiting, so we can have
    // many readers active all at once
    if (NWriters == 1 || WaitingWriters > 0) {
  
        ++WaitingReaders;
  
        // Otherwise, a reader waits (maybe many do)
        Wait(CanRead);
  
        --WaitingReaders;
    }
  
    ++NReaders;
    Signal(CanRead);
}
  
Void EndRead()
{
  
    // When a reader finishes, if it was the last reader,
    // it lets a writer in (if any is there).
    if (--NReaders == 0)
  
        Signal(CanWrite);
}

Entendiendo la solución: –

  • Quiere ser justo.
  1. Si un escritor está esperando, los lectores hacen cola.
  2. Si un lector (u otro escritor) está activo o esperando, los escritores hacen cola.
  3. Esto es bastante justo, aunque una vez que deja entrar a un lector, permite que TODOS los lectores en espera entren a la vez, incluso si algunos aparecieron «después» de otros escritores en espera.

  • El código está «simplificado» porque sabemos que solo puede haber un escritor a la vez.
  • También aprovecha el hecho de que la señal no funciona si nadie está esperando.
    1. En el código «EndWrite» (señala CanWrite sin verificar si hay escritores en espera)
    2. En el código EndRead (lo mismo)
    3. En StartRead (señales CanRead al final)

    Con Semaphores nunca tuvimos una solución «justa» de este tipo. De hecho, se puede hacer, pero el código es bastante complicado. ¡Aquí la solución directa funciona de la manera deseada! Los monitores son menos propensos a errores y también más fáciles de entender.

    Publicación traducida automáticamente

    Artículo escrito por Siddhant-Bajaj y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *