Solución al problema de los baños públicos — Sistemas operativos


Problema: Una oficina tiene en su quinta planta un único lavabo que es unisex. 

Para el funcionamiento correcto de este lavabo los empleados han de cumplir las siguientes reglas: 

  • En el lavabo no puede haber hombres y mujeres a la vez.
  • La capacidad máxima es de 3 personas

Escribe el pseudocódigo de los procesos Hombre() y Mujer() para que se garanticen estas 

dos condiciones en el acceso al lavabo mediante semáforos. 

El main del programa seria el siguiente:

/** Se definen las CONSTANTES GLOBALES **/

#define AFORO 3

#define WOMEN 5

#define MEN 6

/** Se definen los SEMAFOROS **/

BATHROOM // Controla las variables que dan acceso al lavabo

menSemaphore // Controla el acceso de los hombres

womenSemaphore // Controla el acceso de las mujeres

colaSemaphore // Controla el acceso a bathroomUsers

/** Se definen las VARIABLES GLOBALES **/

int bathroomUsers = 0; // Personas que hay dentro del baño

void main()

{

int i;

Init(BATHROOM, AFORO);

Init(menSemaphore, 1);

Init(womanSemaphore, 1);

Init(colaSemaphore, 1);

for (i = 0  ; i < WOMEN ; i++)

{

Pthread_create(women()); //Creamos a una mujer

}

for (i = 0 ; i < MEN ; i++)

{

Pthread_create(men()); //Creamos a un hombre

}

for(i = 0; i < WOMEN; i++) pthread_join(women()) //Espera a todas las mujeres

for(i = 0; i < MEN; i++) pthread_join(men()); //Espera a todas las mujeres

}


La función Hombre (en nuestro programa men()), seria como sigue:

void * men(void * id)

{

wait(colaSemaphore);

wait(menSemaphore);

bathroomUsers++;

if( bathroomUsers == 1 ) //Soy el único hombre en el baño

{

wait(womanSemaphore);

}

signal(menSemaphore);

signal(colaSemaphore);

wait(BATHROOM); //Entrada a la sección critica

//SC

signal(BATHROOM); //Salida de la sección critica

wait(colaSemaphore);

wait(menSemaphore);

bathroomUsers--;

if (bathroomUsers == 0)

{

signal(womanSemaphore);

}

signal(menSemaphore);

signal(colaSemaphore);

pthread_exit(void);

}


Para la mujer (prácticamente igual que antes):

void * women(void * id)

{

wait(colaSemaphore);

wait(womanSemaphore); //Bloqueo para mujeres, cuando no les toca.

bathroomUsers++;

if(bathroomUsers == 1 ) //Soy la única mujer en el baño

{

wait(menSemaphore); //Bloqueo para hombres, cuando no les toca

}

signal(womanSemaphore);

signal(colaSemaphore);

wait(BATHROOM); //Entrada a la SC

// SC

signal(BATHROOM); // Salida de la SC

wait(colaSemaphore);

wait(womanSemaphore);

bathroomUsers--;

if (bathroomUsers == 0)

{

signal(menSemaphore);

}

signal(womanSemaphore);

signal(colaSemaphore);

pthread_exit(void);

}


Significado de las funciones escritas en el programa:

  • men() –> Llamada a la función que realiza el comportamiento de un hombre en el programa
  • women() –> Llamada a la función que realiza el comportamiento de una mujer en el programa
  • wait() –> Función que comprueba el valor de un semáforo que se le pasa por parámetro y si su valor es positivo continua la ejecución normal del programa, en caso contrario bloquea el hilo que lo llamo hasta que se llame a signal y el valor del semáforo sea 1. Ademas decrementa el valor del semáforo en 1.
  • signal() –> Recibe como parámetro un semáforo y aumenta su valor en uno. En el programa no se especifica, pero si recibe un semáforo binario como parámetro y se hace signal sobre el cuando esta abierto no tiene efecto. En caso de no ser binario el semáforo siempre se incrementara en 1.
  • init() –> Recibe dos parámetros, un semáforo y un valor entero respectivamente. Lo que realiza la función es la inicialización de un semáforo. Si recibe como segundo parámetro 1 o 0, se trata de la inicialización de un semáforo binario, en caso contrario es un semáforo no binario.
  • pthread_create() –> Recibe una serie de parámetros entre los que se encuentra la función que va a iniciar el hilo resultante. La función crea un nuevo hilo del programa y lo inicia en la función indicada.
  • pthread_join() –> Recibe varios parámetros entre los que destaca el identificador de cada hilo, y espera hasta que dicho hilo haya terminado la ejecución para continuar el programa.
  • pthread_exit() –> Terminal el hilo y devuelve lo que se le pase como parámetro, en nuestro programa devuelve void.

Aunque esta escrito el código como si fuese a codificarse en C, en realidad las funciones no están completas, como queda indicado con las funciones pthread_create o pthread_join. Estás funciones reciben mas parámetros que no han sido especificados en el ejercicio pero que pueden ser consultados fácilmente en la web o con un man <nombre de la función>

Ademas, en las secciones criticas del programa, es decir, cuando un hombre o una mujer están usando el lavabo, no hay nada implementado que indique que es lo que hacen. Cuando se vaya a codificar el problema probablemente se de cuenta de que en dichas secciones le gustaría añadir más cosas, como por ejemplo un tiempo de uso del lavabo y /o una advertencia por pantalla que indique que la persona xxxx esta usando el lavabo.

Nota: estos códigos solo son un esquema de como resolver el trabajo.

Autores:  Adrian Antonio Aranda Gutierrez | Antonio Porras Perez | Pedro José Piquero Plaza