PRACTICA CON SEMAFOROS

¡¡¡¡¡¡Bienvenidos a nuestra pagina WEB!!!!!!! :

Si quieres navegar por nuestra practica, esto es lo que te ofrecemos (sugerimos la vean para ampliar sus conocimientos sobre la materia):

************************************************************************************************

************************************************************************************************

ENUNCIADO DEL PLOBLEMA:

Un estudiante que se especializa en antropologia y sigue una asignatura secundaria en computacion se ha comprometido en un proyecto de investigacion para observar si los mandriles africanos se les puede ensenar estacamientos. Localiza un canon profundo y sujeta una cuerda a traves de el, de manera que los mandriles puedan cruzar pasando a mano. Varios mandriles pueden atravesar al mismo tiempo, siempre que vayan en la misma direccion. Si los mandriles que viajan hacia el norte y los que viajan hacia el sur abordan la cuerda al mismo tiempo se producir  un estancamiento (los mandriles se encuentran en el centro ) porque es imposible que un mandril pase sobre otro estando suspendidos sobre el canon. Si uno de ellos desea atravesar el canon, debe verificar que ningun mandril este atravesando el canon en ese momento en direccion contraria.

volver al menu

************************************************************************************************

************************************************************************************************

DOCUMENTACION DEL PROGRAMA:

Se considera cada mandril como un proceso, y el puente es el recurso compartido, de modo que, para que los mandriles que vienen del norte y los que vienen del sur no coincidan en el centro del puente utilizamos dos semaforos (permisoN y permisoS). Hemos seguido el sigiente protocolo:

FUNCIONES DEL PROGRAMA:

A estas dos funcines se les manda por argumentos: un entero que especifica el mandril que llega a ese camino. un puntero al fichero de salida

Existe una variable global (puente), definida de tipo PUENTE, que es una estructura en la que se encuentran los semaforos y las variables que regulan el paso de los mandriles por el puente.

DEPENDENCIAS:

VARIABLE DE MEMORIA COMPARTIDA: La variable de memoria compartida es una estructura del tipo:

¡¡¡¡¡ NOTA IMPORTANTE !!!: En una primera version del programa en la funciones caminoNorte() se puso como condicion de entrada en el bucle:

lo que producia un interbloqueo. Por ejemplo: Si hay un mandril del norte cruzando el puente y tres del sur esperando, el siguiente(s) mandril(es) del norte espera(n), lo cual es erroneo. Ademas, los mandriles del sur siguen sin poder entrar, porque turnoN=TRUE y esperandoN > 0; por su lado los mandriles del norte tampoco podran entrar porque turnoS=TRUE y esperandoS > 0.

Para solucionar este problema cambiamos la condicion de entrada por:

Es obvio que NO(turnoN=TRUE) es equivalente a turnoS=TRUE. Esta condicion de entrada es analoga para la funcion caminoSur().

volver al menu

***********************************************************************************************

***********************************************************************************************

LIBRERIAS:

Hemos utilizado las siguientes librerias:

rshmem.c:

/* rshmem.c

Fichero con funciones de creación de memoria compartida y varias de utilidad. */

#define RUTINAS_SHMEM

#include "rshmem.h"

/* Crea memoria compartida. * - el manejador de memoria es interno * - manda mensajes de error por salida de error estándar. */ int crearMemoria() { char *funcName = "crearMemoria"; if ((shmid=shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE))<0) { fprintf(stderr, "%s: error de shmget()\n", funcName); } else if ((memoria=shmat(shmid, 0, 0)) == (void *) -1) { fprintf(stderr, "%s: error de shmat()\n", funcName); } else { return TRUE; } return FALSE; }

/* Destruye la memoria compartida creada por crearMemoria() */ int eliminarMemoria() { char *funcName = "eliminarMemoria"; if (shmctl(shmid, IPC_RMID, 0) < 0) { fprintf(stderr,"%s: error de shmctl()\n", funcName); return FALSE ; } else return TRUE ; }

/* Coloca una semilla en el temporizador del bucle de * tiempoPasa() */ void origenTiempo(){ srand((unsigned int) time(NULL)) ; }

/* Rutina que hace pasar un poco de tiempo con un bucle * sencillo */ void tiempoPasa() { unsigned int i; int a=3;

/* Los parametros "50" y "2" dependen mucho de la velocidad * de la computadora y de la configuracion del SO. Espero que * funcionen bien */ for (i=rand()/50; i>0; i--) a = a%3 + i; }

rshmem.h:

/*rshmem.h

Fichero de cabecera con definiciones y declaraciones para usar memoria compartida. */

#include <stdio.h> #include <time.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h>

#define ARRAY_SIZE 4000 #define MALLOC_SIZE 10000 #define SHM_SIZE 10000 #define SHM_MODE (SHM_R | SHM_W) /* read/write */

#define TRUE 1 #define FALSE 0

#ifdef RUTINAS_SHMEM static int shmid; /* handler de memoria compartida */ char *memoria; /* puntero a zona de memoria compartida */ #else extern char *memoria; #endif

/* Prototipos de funciones de memoria compartida */

void origenTiempo(); void tiempoPasa(); int crearMemoria() ; int eliminarMemoria() ;

#define TP tiempoPasa();

semaph.c:

/*********************************

Provee un interface mas sencillo de entender que las llamadas a sistema de semaforos de System V. Hay 7 rutinas disponibles:

* id = semCreate(key, initval); # Crear con un valor inicial o abrir.

* id = semOpen(key); # Abrir (debe existir ya)

* Se disegna un semaforo soportado por un conjunto de tres, dos de ellos auxiliares. (Los semaforos se crean por arrays)

********************************************************/

#include <stdio.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#include <errno.h>

void semOp(int, int);

int semCreate(key_t, int);

int semOpen(key_t);

void semRm(int);

void semClose(int);

void semWait(int);

void semSignal(int);

#define BIGCOUNT 10000 /* Valor inicial para el contador de procesos */

/* Define los arrays de operaciones del semaforo para llamadas a

* semop().

*/

/****************************************************************************

* Crea un semaforo con un valor inicial especificado.

* Si el semaforo existe, no se inicializa (por su puesto).

* Se devuelve la identidad del semaforo si todo va bien, si no -1.

*/

int semCreate(key_t key, int initval) {

if (key == IPC_PRIVATE)

deNuevo:

/****************************************************************************

* Abre un semaforo que debe existir ya.

* Esta funcion deberia de usarse, en vez de semCreate(), si en la llamada

* se sabe que el semaforo deberia ya existir. Por ejemplo un cliente

* de un par cliente-servidor podria utilizarla, si es responsabilidad del

* servidor crear el semaforo. * Se vuelve la identidad del semaforo si va bien, si no -1.

*/

int semOpen(key_t key) {

/* Decrementa el contador de procesos. No necesitamos un bloqueo

* para hacer esto. */

/****************************************************************************

* Borrar un semaforo.

* Se supone que esta llamada se realiza desde un servidor en operaciones como

* apagarServidor ... No importa si los otros procesos estan usandolo o no.

* El resto de los procesos deberian emplear semClose().

*/

void semRm(int id) {

/****************************************************************************

* Cerrar el semaforo.

* Funcion por proceso que decrementa el numero de procesos activos en el

* semaforo. Se emplea al salir. Si el proceso es el ultimo destruye el

* semaforo.

*/

void semClose(int id) {

/****************************************************************************

* Espera hasta que el valor del semaforo sea mayor que 0, entonces

* decrementa en 1 y vuelve. Operador wait, DOWN (Tanenbaum) o P (Dijkstra).

*/

void semWait(int id) {

}

/****************************************************************************

* Incrementar el semaforo en 1. Operador segnal, UP (Tanenbaum) o

* V (Dijkstra).

*/

void semSignal(int id) {

}

/****************************************************************************

* Operacion generica de semaforo:

* incrementar o decrementar cierta cantidad positiva o negativa, distinta

* de cero.

*/

void semOp(int id, int value) {

volver al menu

************************************************************************************************

************************************************************************************************

IMPLEMENTACION:

/* librerias*/

#include "rshmem.h"

#include <sys/sem.h>

/*numero de mandriles que vienen por el norte*/

#define NummandrilN 10

/* numero de mandriles que vienen por el sur*/

#define NummandrilS 15

/*estructura de variable compartida que sirve para regular el paso de los mandtiles por el puente*/

typedef struct puente{

}PUENTE;

PUENTE *puente; /* declaracion global */

/*DECLARACION DE LA FUNCION caminoNorte */

void caminoNorte(int mandrilN,FILE *pf){

}/*FIN FUNCION*/

/*DECLARACION DE LA FUNCION caminoSur*/

void caminoSur(int mandrilS,FILE *pf){

}/*FIN FUNCION*/

void main(){

} /* FIN MAIN */

volver al menu

************************************************************************************************

************************************************************************************************

SALIDA
El mandril 1 del norte ha pasado
El mandril 3 del norte ha pasado
El mandril 5 del norte ha pasado
El mandril 6 del norte ha pasado
El mandril 8 del norte ha pasado
El mandril 7 del norte ha pasado
El mandril 0 del sur ha pasado
El mandril 9 del norte ha pasado
El mandril 2 del sur ha pasado
El mandril 1 del sur ha pasado
El mandril 4 del sur ha pasado
El mandril 3 del sur ha pasado
El mandril 6 del sur ha pasado
El mandril 5 del sur ha pasado
El mandril 7 del sur ha pasado
El mandril 8 del sur ha pasado
El mandril 9 del sur ha pasado
El mandril 10 del sur ha pasado
El mandril 11 del sur ha pasado
El mandril 12 del sur ha pasado
El mandril 13 del sur ha pasado
El mandril 14 del sur ha pasado
volver al menu

************************************************************************************************

************************************************************************************************

AUTORAS:

volver al menu