PRACTICA
DE SISTEMAS OPERATIVOS
DOCUMENTACIÓN:
Esta práctica pretende dar
solución al problema del monitor mediante la implementación
de éste con semáforos.
Tenemos una variable global sobre
la que queremos realizar tres operaciones:
- Leer variable
- Escribir variable
- Incrementar variable
Esto lo hacemos con tres funciones
a las que se accede a través de un monitor . Hay dos procesos que
intentan entrar en el monitor para realizar estas operaciones, para sincronizar
los procesos y el monitor utilizamos dos semáforos:
- Un semáforo para que solo
un proceso pueda realizar una conversación con el monitor.
- Otro para que el monitor esté
dormido mientras no esté realizando ninguna operación para
ningún proceso.
Para el manejo de los semáforos
utilizamos semaph.c
.
Para decirle al monitor la operación
que tiene que realizar utilizamos una nueva variable ( llamada "operacion"
) , que al igual que la variable global ("recurso") van sobre
memoria compartida. Esta variable "operacion" es aleatoria y
su valor indica al proceso la operación que tiene que realizar en
cada momento.
Para el manejo de memoria compartida
utilizamos rshmem.c .
volver al principio
#include "rshmem.h"
#include <sys/sem.h>
#include <stdlib.h>
#include <time.h>
/*Funcion que lee la variable*/
int leer(int *variable){
return(*variable);
}
/*Funcion que escribe en la variable*/
void escribir(int *variable){
- int ayuda;
- printf("\nEscriba un numero
entero:");
- scanf("%d",&ayuda);
- *variable=(int)ayuda;
}
/*Funcion que incrementa la variable*/
void incrementa(int *variable){
(*variable)++;
}
/*Monitor*/
void monitor(int pid,float *operacion,int
*variable,int s){
- semWait(s);
- (*operacion)=rand();
- (*operacion)/=RAND_MAX;
- (*operacion)*=3;
- if((*operacion)<1){
- leer(variable);
- printf("\n Lee la variable
var=%d",*variable);
- }else if((*operacion)<2){
- escribir(variable);
- printf("\n Escribe la variable
var=%d",*variable);
- }else{
- incrementa(variable);
- printf("\n Incrementa la variable
var=%d",*variable);
- }
- semSignal(s);
}
/****FUNCION PRINCIPAL****/
void main(){
- int *recurso; /*puntero a memoria
compartida*/
- int *marcaFin; /*marca de fin del
proceso hijo*/
- float *operacion; /*puntero a memoria
compartida*/
- int pid; /*pid de los procesos*/
- int s; /*semaforo para que un solo
proceso pueda entrar en el monitor*/
- int m; /*semaforo para que el monitor
este dormido mientras no realiza ninguna operacion*/
- key_t claveS;
- key_t claveM;
- time_t t;
- /*Obtener una clave cualquiera
para el recurso ipc*/
- if ((key_t)-1 == (claveS = ftok("prog.c",'s'))){
- fprintf(stderr,"main:error
al crear la clave con ftok()\n");
- exit(1);
- }
- if ((key_t)-1 == (claveM = ftok("prog.c",'m'))){
- fprintf(stderr,"main:error
al crear la clave con ftok()\n");
- exit(1);
- }
- /*Crear el semaforo*/
- if (-1 == (s=semCreate(claveS,1))){
- fprintf(stderr,"main:No puede
crear semaforo\n");
- exit(1);
- }
- if(-1 == (m=semCreate(claveM,1))){
- fprintf(stderr,"main:No puede
crear semaforo\n");
- semClose(s);
- exit(1);
- }
- /*Crear memoria compartida*/
- if (!crearMemoria()){
- fprintf(stderr,"error de crear
Memoria\n");
- semClose(s);
- semClose(m);
- exit(1);
- }
- recurso = (int*) memoria;
- marcaFin = recurso + sizeof(int);
- operacion =(float*) marcaFin +sizeof(float);
- *recurso=0;
- *marcaFin='p';
- srand((unsigned)time(&t));
- /****PROCESO 1****/
- if ((pid=fork())!=0){
- int i;
- for(i=0;i<10;i++){
- semWait(m); TP
- printf("\n Soy el proceso
1");
- monitor(pid,operacion,recurso,s);
- semSignal(m); TP
- }
- while(*marcaFin!='x'); /*espera
el hijo*/
- if (!eliminarMemoria()) /*eliminar
memoria compartida*/
- fprintf(stderr, "error de
eliminarMemoria\n");
- semClose(s);
- semClose(m);
- exit(0);
- /****PROCESO 2****/
- }else{
- int i;
- if(-1==(s=semOpen(claveS)))
- fprintf(stderr,"No tengo cualificador
de s \n");
- if(-1==(m=semOpen(claveM)))
- fprintf(stderr,"No tengo cualificador
de m \n");
- for(i=0;i<10;i++){
- semWait(m); TP
- printf("\n Soy el proceso
2");
- monitor(pid,operacion,recurso,s);
- semSignal(m); TP
- }
- semClose (s);
- semClose (m);
- *marcaFin ='x'; /* marca de fin
del proceso */
- exit(0);
- }
}
volver atras
Ejemplo de una posible SALIDA
del programa:
Soy el proceso 2
Escriba un numero entero:3
Escribe la variable var=3
Soy el proceso 1
Escriba un numero entero:8
Escribe la variable var=8
Soy el proceso 2
Incrementa la variable var=9
Soy el proceso 2
Incrementa la variable var=10
Soy el proceso 2
Escriba un numero entero:6
Escribe la variable var=6
Soy el proceso 1
Incrementa la variable var=7
Soy el proceso 1
Incrementa la variable var=8
Soy el proceso 1
Escriba un numero entero:25
Escribe la variable var=25
Soy el proceso 2
Lee la variable var=25
Soy el proceso 2
Lee la variable var=25
Soy el proceso 2
Lee la variable var=25
Soy el proceso 2
Escriba un numero entero:7
Escribe la variable var=7
Soy el proceso 1
Lee la variable var=7
Soy el proceso 1
Lee la variable var=7
Soy el proceso 1
Escriba un numero entero:21
Escribe la variable var=21
Soy el proceso 2
Incrementa la variable var=22
Soy el proceso 2
Lee la variable var=22
Soy el proceso 1
Incrementa la variable var=23
Soy el proceso 1
Lee la variable var=23
volver atras
AUTORAS:
volver al principio