Para recordarlo, para compartirlo. Coches que quieren pasar por un puente, desde la izquierda o desde la derecha. No pueden pasar de ambos lados a la vez. Cuando pasen 5 coches seguidos de un lado y haya esperando en el lado contrario se desbloquean a éstos últimos.
Todo esto sólo usando semáforos y hebras Posix en C. ¿Fácil? ¡Ja!
Como es mu largo, tras el salto.
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
#define NUM 20
//s1 bloquea si estan pasando coches de la derecha
//s2 bloquea si estan pasando coches de la izquierda
sem_t s1,s2,em;
int cochesder=0, cochesizq=0, espeizq=0, espeder=0;
void * coches_izq (){
//Pre protocolo
sem_wait(&em);
if(cochesder != 0 || cochesizq==5){
espeizq++;
sem_post(&em);
sem_wait(&s1);
sem_wait(&em);
espeizq--;
cochesizq++;
sem_post(&em);
}
else{
cochesizq++;
sem_post(&em);
}
//Coche de la izq pasa
printf("Coche IZQ pasando: espeder=%d izq=%d \n",
espeder,cochesizq);
sleep(0);
//Post protocolo
sem_wait(&em);
cochesizq--;
if(cochesizq == 0 && espeder>0){
int i;
for(i=0;i<5;i++)
sem_post(&s2);
}
sem_post(&em);
pthread_exit(NULL);
}
void * coches_der (){
//Pre protocolo
sem_wait(&em);
if(cochesizq != 0 || cochesder==5){
espeder++;
sem_post(&em);
sem_wait(&s2);
sem_wait(&em);
espeder--;
cochesder++;
sem_post(&em);
}
else{
cochesder++;
sem_post(&em);
}
//Coche de la izq pasa
printf("Coche DER pasando: der=%d espeizq=%d \n",
cochesder,espeizq);
sleep(0);
//Post protocolo
sem_wait(&em);
cochesder--;
if(cochesder == 0 && espeizq>0){
int i;
for(i=0;i<5;i++)
sem_post(&s1);
}
sem_post(&em);
pthread_exit(NULL);
}
int main (){
int err, i;
pthread_t thr_izq[NUM];
pthread_t thr_der[NUM];
sem_init(&s1,0,0);
sem_init(&s2,0,0);
sem_init(&em,0,1);
//Creamos los coches de la izq
for(i=0;i<NUM;i++){
err = pthread_create(&thr_izq[i],NULL,coches_izq,NULL);
if ( err ) printf("%d\n", err);
err = pthread_create(&thr_der[i],NULL,coches_der,NULL);
if ( err ) printf("%d\n", err);
}
pthread_exit(NULL);
}