Está en la página 1de 4

Sistemas Operativos Producto Académico N° 1

Producto Académico N° 1
Pregunta 1:

Explicar en el código donde y como se produce la exclusión mutua en "El problema de


lectores/escritores". William Stallings.

EXPLICACIÓN
Se considera a cada usuario (lector y escritor) como dos procesos y al fichero en cuestión como
un recurso. De modo que, para que un proceso acceda al recurso que necesita, tenemos que
considerar a cada usuario (lector y escritor) como dos semáforos. Estos semáforos son binarios
y valen 0 si el recurso (fichero) está siendo utilizado por otro proceso y 1 si dicho recurso está
disponible.
La solución de este problema se basa en implementar un algoritmo eficiente en el manejo de
semáforos y memoria compartida que seguidamente describimos. A lo largo del programa se
utilizan funciones necesarias para el manejo de memoria compartida y manejo de semáforos.
Para que el problema esté bien resuelto se tiene que cumplir:
- Solamente puede haber un escritor al mismo tiempo, si un escritor o un lector quiere utilizar
la base de datos y hay un escritor utilizándola, entonces debe esperar.
- Puede haber varios lectores utilizando la base de datos al mismo tiempo, pero si un escritor
quiere usar la base de datos mientras los lectores la usan, deberá esperar.
- El último lector en usar la base de datos debe habilitarla para que pueda ingresar el siguiente
escritor que estaba esperando la base de datos o en todo caso al siguiente proceso que
requiera usarla.
- No se puede hacer esperar a ningún proceso lector si ningún proceso escritor accede al
recurso.
- Cuando un escritor debe realizar su tarea, debe ocurrir cuanto antes, sin que deban interferir
los procesos lectores. (Para ello se establecen prioridades).

SOLUCIÓN AL PROBLEMA
 En esta solución, el primer lector en obtener acceso a la base de datos realiza una operación
down en el semáforo bd. Los siguientes lectores simplemente incrementan un contador
llamado cl.
 A medida que los lectores van saliendo, decrementan el contador y el último realiza una
operación up en el semáforo, para permitir que un escritor bloqueado (si lo hay) entre.
 Ahora suponga que aparece un escritor. Tal vez éste no sea admitido a la base de datos, ya
que los escritores deben tener acceso exclusivo y por ende, el escritor se suspende. Más
adelante aparecen lectores adicionales. Mientras que haya un lector activo, se admitirán los
siguientes lectores.
 Como consecuencia de esta estrategia, mientras que haya un suministro continuo de
lectores, todos entrarán tan pronto lleguen. El escritor estará suspendido hasta que no haya
un lector presente. Si llega un nuevo lector, por decir cada 2 segundos y cada lector requiere
5 segundos para hacer su trabajo, el escritor nunca entrará.
 Para evitar esta situación, el programa se podría escribir de una manera ligeramente distinta:
cuando llega un lector y hay un escritor en espera, el lector se suspende detrás del escritor,
en vez de ser admitido de inmediato. De esta forma, un escritor tiene que esperar a que
terminen los lectores que estaban activos cuando llegó, pero no tiene que esperar a los
lectores que llegaron después de él.

1|Página
Sistemas Operativos Producto Académico N° 1

DESCRIPCIÓN

Escribir ( ); Esta función implementa el acceso a un recurso compartido, que será la variable
que contabiliza el total de veces que el usuario escribe. En esta función se han incluido varias
llamadas al macro TP. Este macro implementa un retardo aleatorio con el fin de dar cierto tiempo
a que ocurran interrupciones que puedan detener la ejecución del proceso en su "cuanto" de
tiempo asignado por el S.O. En nuestro caso, es necesario realizar unas cuantas llamadas para
dar tiempo a que todos los usuarios tengan oportunidad de escribir.

Lectura ( ); Permite que el lector pueda acceder al recurso. Una vez que acaba de leer se
encarga de dejar el recurso para que sean de nuevo utilizado (por él o por otros). Para ello se
basa en funciones de manejo de semáforos y memoria compartida.

LECTORES.C
#include "rshmem.h"
#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[]){
/*DECLARACION DE VARIABLES*/
int contador=0;
FILE *fpl,*fpe;
int i,n;
char texto [250],c;
int mutex_s; /*semáforo 1*/
int mutex_w; /*semáforo 2*/
key_t claveMutex_s; /*clave semáforo 1*/
key_t claveMutex_w; /*clave semáforo 2*/
/*CONTROL DEL PASO DE ARGUMENTOS*/
if(argc!=2){
fprintf(stderr,"main:error en el paso de
argumentos\n");
exit(3);
}
/*obtener una clave cualquiera para el recurso ipc*/
if((key_t)-1==(claveMutex_s = ftok("lectores.c",'s'))){
fprintf(stderr,"main:Error al crear la clave con
ftok\n");
exit(1);
}
if((key_t)-1==(claveMutex_w = ftok("lectores.c",'s'))){
fprintf(stderr,"main:Error al crear la clave con
ftok\n");
exit(1);
}
/*crear el semáforo*/

2|Página
Sistemas Operativos Producto Académico N° 1

if(-1==(mutex_s=semCreate(claveMutex_s,1))){
fprintf(stderr,"main:No se puede crear el semáforo
1\n");
exit(1);
}
if(-1==(mutex_w=semCreate(claveMutex_w,1))){
fprintf(stderr,"main:No se puede crear el semáforo
2\n");
exit(1);
}
/*crear zona de memoria compartida*/
if(!crearMemoria())
fprintf(stderr,"Error al crear memoria compartida\n");
if(0!=fork()){ /*PROCESO ESCRITOR*/
if((fpl=fopen(argv[1],"r+"))==NULL){
printf("Error en la apertura del fichero %s \n",argv[1]);
exit(-1);
semClose(mutex_w);
}
rewind(fpl);
for(i=0;i<3;i++){
printf ("Dime una frase que quieras escribir:");
gets(texto);
n=strlen(texto);
semWait(mutex_w);
fwrite(texto,(n*sizeof(char)),1,fpl);
semSignal(mutex_w);
semClose(mutex_w);
exit(0);
}
fclose(fpl);
}
else{
/*PROCESO LECTOR*/
if((fpe=fopen(argv[1],"w"))==NULL){
fprintf(stderr,"Error no se puede abrir el fichero %s
\n",argv[1]);
semClose(mutex_w);
semClose(mutex_s);
exit(2);
}
for(i=0;i<3;i++) {
semWait(mutex_s);
contador ++;
if(contador==1)

3|Página
Sistemas Operativos Producto Académico N° 1

semWait(mutex_w);
while(!feof(fpe)){
semSignal(mutex_s);
fread((char *)c,sizeof(char),1,fpe);
semWait(mutex_s);
printf("%c",c);
}
contador --;
if(contador==0)
semSignal(mutex_w);
semSignal(mutex_s);
semClose(mutex_s);
semClose(mutex_w); /*CERRAMOS LOS FICHEROS*/
fclose(fpe);
}
/*eliminamos memoria compartida*/
if(!eliminarMemoria()){
fprintf(stderr,"Error al eliminar la memoria
compartida");
exit(9);
}
}
return (0);
}

4|Página

También podría gustarte