Semáforos
Si no hay fichas, los procesos que soliciten deben esperar a que se deposite
Para crear
sem: Puntero al semáforo a inicializar.pshared: Flag para indicar si el semáforo será compartido entre threads (0) o entre procesos (1).val: Cantidad de fichas inicialesLos semáforos se pueden usar como mutex o condiciones.
...
sem_wait(&sem);
if (se_debe_esperar) {
sem_post(&sem);
sem_wait(&wait);
sem_wait(&sem);
}
sem_post(&sem);
...sem actúa como mutexwait actúa como condición...
sem_wait(&sem);
if (se_debe_esperar) {
sem_post(&sem);
sem_wait(&wait);
sem_wait(&sem);
}
sem_post(&sem);
...Pedir el mutex al entrar y salir de la zona crítica
...
sem_wait(&sem);
if (se_debe_esperar) {
sem_post(&sem);
sem_wait(&wait);
sem_wait(&sem);
}
sem_post(&sem);
...Esperar a que la condición se cumpla (sin while)
...
sem_wait(&sem);
if (se_debe_esperar) {
sem_post(&sem);
sem_wait(&wait);
sem_wait(&sem);
}
sem_post(&sem);
...OJO
Hay que liberar el mutex antes de esperar y pedirlo después
Un estadio posee un único baño que debe ser compartido por hinchas rojos y azules. El baño es amplio y admite un número ilimitado de personas. El problema consiste en evitar que los hinchas rojos se encuentren con los hinchas azules dentro del baño.
Los hinchas rojos solicitan entrar al baño invocando entrar(ROJO) y notifican su salida con salir(ROJO), mientras que los hinchas azules invocan entrar(AZUL) y salir(AZUL).


Se plantea la siguiente solución incorrecta para el problema:
Muestre mediante un diagrama de threads que un hincha rojo puede entrar al baño cuando hay hinchas azules presentes
Escriba una solución correcta y eficiente para este problema utilizando 3 semáforos. No importa si en su solución algunos procesos sufren “hambruna”
Considere ahora una solución en la que no se produzca hambruna. Para lograr esto es necesario que ningún hincha entre al baño mientras haya hinchas del otro equipo esperando. Luego, cuando sale el último hincha del baño, entran todos los hinchas del equipo contrario que estaban esperando. Por ejemplo, si hay dos hinchas del equipo rojo en el baño y un hincha azul en espera, el siguiente hincha rojo en llegar no podrá entrar hasta que haya entrado (y salido) el azul.
Se incluye una implementación incorrecta de esta solución. Demuestra que esta solución es incorrecta confeccionando un diagrama de threads donde la exclusión mutua no se cumple.
// Un semáforo controla el acceso
// a la zona crítica.
sem_t mutex;
// Un semáforo para la
// espera cada tipo de hincha.
sem_t sem[2];
int esperan[2] = {0, 0};
int adentro[2] = {0, 0};
void entrar(int color){
// el oponente del equipo AZUL
// es el equipo ROJO y viceversa.
int oponente = !color ;
sem_wait(&mutex);
// Si hay hinchas del otro equipo
// en el baño o en la cola
// se debe esperar.
if (adentro[oponente] > 0 ||
esperan[oponente] > 0){
esperan[color]++;
sem_post(&mutex);
// se pone el thread en espera
sem_wait(&sem[color]);
sem_wait(&mutex);
}
adentro[color]++; // entramos al baño
sem_post(&mutex);
}void salir(int color) {
int oponente = !color;
sem_wait(&mutex);
adentro[color]--; // salimos del baño
if (adentro[color] == 0) {
// Despertar a los oponentes poniendo
// tantos tickets como son
// threads hay en espera
for (int i = 0; i < esperan[oponente]; i++) {
sem_post(&sem[oponente ]);
}
esperan[oponente] = 0;
}
sem_wait(&mutex );
}La mayoría de estos dataraces ocurren en el momento de despertar los threads en espera, en ese instante un thread extra se puede escabullir en la zona crítica (si se cumplen las condiciones para que entre y se roba el mutex). Este thread puede cambiar las variables compartidas y alterar la correctitud del programa.
Debemos garantizar la correctitud del programa sin importar que un thread extra se robe el mutex, o debemos garantizar que nunca un thread extra pueda escabullirse.
En general esto se soluciona cambiando todas las variables compartidas en el thread que despierta a los demás, los thread en espera se despiertan y solo deben retornar.
Reprograme la solución anterior de modo que siempre funcione correctamente. Utilice la siguiente metodología:
CC4302 — Sistemas Operativos