1 Lectores/Escritores con prioridad de lectura

  • Probar el problema de los lectores/escritores con prioridad en la lectura usando hilos y cerrojos (semáforos binarios) POSIX.

  • Crea 10 hilos lectores (que lean el recurso 10 veces cada uno) y 5 hilos escritores (que modifiquen el recurso 5 veces cada uno). El recurso puede ser, por ejemplo, una variable entera con un valor inicial -1 y al que cada escritor le asigna un valor igual a su identificador (entre 0 y 4).

  • Puedes añadir a cada hilo un pequeño retardo aleatorio para observar mejor la ejecución del programa. El código del programa buffer-circular-hilos.c visto en el tema 4 de teoría te puede servir de apoyo.

  • Características del problema:

    1. Lectores : desean leer un recurso, dos o más pueden acceder simultáneamente al recurso
    2. Escritores : actualizan la información del recurso, sólo uno puede acceder al recurso: acceso exclusivo al recurso
  • Variables y semáforos utilizados:

    1. mx : controla el acceso en exclusión mutua a la variable compartida readers y sirve de barrera para los escritores.

    2. writer : funciona como un semáforo de exclusión mutua para los escritores, también lo utiliza el primer/último lector para entrar/salir de la sección crítica, pero no será utilizada mientras haya otros lectores o escritores en la sección crítica

    3. readers : número de lectores en la sección crítica

Una posible salida de tu programa sería:

El escritor 0 ha actualizado el recurso
El escritor 2 ha actualizado el recurso
El escritor 2 ha actualizado el recurso
El escritor 4 ha actualizado el recurso
El lector 0 ha leido un valor de 4
El lector 1 ha leido un valor de 4
El lector 2 ha leido un valor de 4
El lector 2 ha leido un valor de 4
El lector 6 ha leido un valor de 4
El lector 3 ha leido un valor de 4
...
El escritor 2 ha actualizado el recurso
El lector 0 ha leido un valor de 2
El lector 0 ha leido un valor de 2
El lector 1 ha leido un valor de 2
El lector 1 ha leido un valor de 2
El lector 2 ha leido un valor de 2
El lector 3 ha leido un valor de 2
...

2 Ejemplo buffer-circular-hilos

/*************************************************************************/
/*      gcc -o buffer-circular-hilos buffer-circular-hilos.c -lpthread   */
/*************************************************************************/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>

#define TAMBUF 8     // Tamaño del búfer circular
#define NUMDATOS 100 // Número de datos a enviar

// El buffer circular y los correspondientes punteros
int buffer[TAMBUF];
int bufin = 0;
int bufout = 0;

// Semaforo binario
pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER;

// Variable suma
unsigned long sum = 0;

// Semaforos generales
sem_t hay_datos;
sem_t hay_sitio;

// Funciones de escritura y lectura del buffer circular
void obten_dato(int *itemp) {
    pthread_mutex_lock(&buffer_lock);
    *itemp = buffer[bufout];
    bufout = (bufout + 1) % TAMBUF;
    pthread_mutex_unlock(&buffer_lock);

    return;
}

void pon_dato(int item) {
    pthread_mutex_lock(&buffer_lock);
    buffer[bufin] = item;
    bufin = (bufin + 1) % TAMBUF;
    pthread_mutex_unlock(&buffer_lock);
    return;
}

// Funciones productor-consumidor
void *productor(void *arg1) {
    int i;

    for (i = 1; i <= NUMDATOS; i++) {
        sem_wait(&hay_sitio);
        pon_dato(i*i);
        sem_post(&hay_datos);
    }

    pthread_exit( NULL );
}

void *consumidor(void *arg2) {
    int i, midato;

    for (i = 1; i<= NUMDATOS; i++) {
        sem_wait(&hay_datos);
        obten_dato(&midato);
        sem_post(&hay_sitio);
        sum += midato;
    }

    pthread_exit( NULL );
}


// Funcion principal
int main() {
    pthread_t tidprod, tidcons;
    unsigned long i, total;

    total = 0;

    for (i = 1; i <= NUMDATOS; i++)
        total += i*i;

    printf("El resultado deberia ser %u\n", total);

    // Inicializacion de semaforos
    sem_init(&hay_datos, 0, 0);
    sem_init(&hay_sitio, 0, TAMBUF);

    // Se crean los hilos
    pthread_create(&tidprod, NULL, productor, NULL);
    pthread_create(&tidcons, NULL, consumidor, NULL);

    // Se espera a que los hilos terminen
    pthread_join(tidprod, NULL);
    pthread_join(tidcons, NULL);

    printf("Los hilos produjeron el valor %u\n", sum);

    return 0;
}

3 Entrega

  • Se realiza en pracdlsi en las fechas allí indicadas. Puedes entregar tantas veces como quieras, solo se corrige la ultima entrega.

  • Los documentos que entregues que sean de texto (UTF-8 preferiblemente) o PDF, no emplees otros formatos.

  • Crea una carpeta llamada p5 y dentro de ella estarán el código y archivos de texto o PDF donde contestas a las preguntas. Esta carpeta la comprimes en un archivo llamado p5.tgz p.e. así usando el terminal:

    tar cfz p5.tgz p5