Dev - C++ - Ayuda con el problema del barbero dormilón

 
Vista:

Ayuda con el problema del barbero dormilón

Publicado por peivcar (1 intervención) el 31/01/2011 19:37:14
Ayuda con el programa barbero dormilón
Hola!

Estoy trabajando en este programa y tengo un problema, quiero poner un semáforo para que "Client ha sigut ates" se imprima antes que "Barber descansant" y si hago esto se queda colgado al hacer ^c, llevo tiempo con estoy y me estoy volviendo loca! Si alguien le apetece echar un vistazo...lo agradecería.


#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <signal.h>

#define VERSIO "1.4"

#define SILLONS 1
#define CADIRES 3
#define MAX_CLIENTS (SILLONS+CADIRES)
#define MAX_GEN_CLI (MAX_CLIENTS+1)

#define T_B 1000
#define F_MAX_SER 7
#define F_MAX_GEN 5
#define F_GEN 3

#define T_MIN_GEN F_GEN*50*T_B
#define T_MAX_GEN F_MAX_GEN*T_MIN_GEN
#define T_MIN_SER 50*T_B
#define T_MAX_SER F_MAX_SER*T_MIN_SER

pthread_t generador_clients[MAX_GEN_CLI];//pa que no es penje el programa per falta de memoria

sem_t s_mutex, s_cadires, s_barber, s_servei, s_servit, s_sillo;

int clients_contador= 0; //donem un numero als fils
int cadires= 0;
int sillo= 0; //per a saber si el sillo esta ocupat
int cli_no_at= 0;
int cli_at= 0;
int becades= 0;
int cli_gen= 0; //clients reals
int sillo_act= 0; //-1 barber, 0 buit, id client
int esta_obert= 0;
int exitus= 0; //eixida que causa la mort

/*SENYALS*/
sigset_t sigset, sigint;
struct sigaction act;

void estadistiques () {
printf("S=%d C=%d G=%d A=%d N=%d B=%d\n"\
,sillo_act, cadires, cli_gen, cli_at, cli_no_at,becades);
}

long alea (long min, long max) {
return(min+1.*(max-min+1)*random()/(RAND_MAX+1.0));
}

void * barber (void * identificacio) {
sem_wait(&s_mutex); //agafar mutex
while (cadires > 0 || esta_obert) {
if (cadires == 0) {
sem_post(&s_mutex); //soltar mutex
becades++;
sillo_act= -1;
fprintf(stdout,"*Barber descansant: ");estadistiques();
sem_wait(&s_barber); //agafar semafor barber
sillo_act= 0;
fprintf(stdout,"*Barber despertat!");estadistiques();
sem_wait(&s_mutex); //agafar mutex
}
sem_post(&s_mutex);//soltar mutex
if (exitus) break; // si esta tancat surt del while per a acabar el fil
sem_post(&s_sillo); //soltar semafor sillo
sem_wait(&s_servei); //agafar semafor servei
usleep(alea(T_MIN_SER,T_MAX_SER));
fprintf(stdout,"*Barber tallant monyo ");estadistiques();
sem_post(&s_servit); //soltar semafor servit
sem_wait(&s_barber);
sem_wait(&s_mutex); //agafar mutex
}
sem_post(&s_mutex); //soltar mutex
pthread_exit(0);
}

void ser_ates (int id) {
sem_post(&s_mutex); //soltar mutex
sem_wait(&s_sillo); //agafar semafor sillo
sem_wait(&s_mutex); //agafar mutex

sillo_act= id;
sillo++;
sem_post(&s_servei); //soltar semafor servei
sem_post(&s_mutex); //soltar mutex
fprintf(stdout,"Client [%d] tallant-se el monyo: ", id);estadistiques();
sem_wait(&s_servit); //agafar semafor servit
sem_wait(&s_mutex); //agafar mutex
cli_at++;
sillo--;
sillo_act= 0;
fprintf(stdout,"Client [%d] ha sigut ates: ", id);estadistiques();
sem_post(&s_barber);
if (cadires > 0){
fprintf(stdout,"Client [%d] ha cridat a un altre client ", id);estadistiques();
sem_post(&s_cadires); //soltar semafor cadires
fprintf(stdout,"-> Client [%d] ha eixit de la barberia: ", id);estadistiques();
}
}

void despertar_barber (int id) {
fprintf(stdout, "Client [%d] desperta a barber ", id);estadistiques();
sem_post(&s_barber); //soltar semafor barber
ser_ates(id);
}

void a_cadires (int id) {
cadires++;
fprintf(stdout, "Client [%d] espera en cadires: ", id);estadistiques();
sem_post(&s_mutex); //soltar mutex
sem_wait(&s_cadires); //agafar semafor cadires
sem_wait(&s_mutex); //agafar mutex
cadires--;
ser_ates(id);
}

void surt_sense_ser_ates (int id) {
cli_no_at++;
fprintf(stdout, "-> Client [%d] surt sense ser ates: ", id);estadistiques();
sem_post(&s_mutex); //soltar mutex
}

void * client (void * identificacio) {
int *passthrough= (int *) identificacio;
int id= *passthrough;
/*fprintf(stderr, "%d\n", id);*/
sem_wait(&s_mutex); //agafar mutex
cli_gen++;
fprintf(stdout, "<- Entra client [%d] ", id);estadistiques();
if (cadires == CADIRES) {
surt_sense_ser_ates(id);
pthread_exit(0);
return;
}
if (sillo < SILLONS && cadires == 0) {
despertar_barber(id);
}else if (cadires < CADIRES) {
a_cadires(id);
}
sem_post(&s_mutex); //soltar mutex
pthread_exit(0);
}

void * genera_client (void * identificacio) {
int *passthrough= (int *) identificacio;//pa pasar el punter correctament
int id;
pthread_t fils_client;
while (esta_obert) {
sem_wait(&s_mutex); //agafar mutex
clients_contador++;
id= clients_contador;
sem_post(&s_mutex); //soltar mutex
pthread_create(&fils_client, NULL, client, (void *) &id);
pthread_join(fils_client, NULL); //espera a que acabe el client
usleep(alea(T_MIN_GEN,T_MAX_GEN));
}
pthread_exit(0);
}

void controlador () {
if (esta_obert) {
printf(" * * * * CARTELL TANCAT * * * *\n");
esta_obert= 0;
}
}

void init_signals(){
/*SENYALS*/
act.sa_flags= 0;
act.sa_handler= controlador;
sigaction(SIGINT, &act, NULL);
sigfillset(&sigset);
sigdelset(&sigset, SIGINT);
sigprocmask(SIG_SETMASK, &sigset, NULL);
}

void init_vars () {
sem_init(&s_mutex, 0, 1);
sem_init(&s_cadires,0,0);
sem_init(&s_barber,0,0);
sem_init(&s_servei,0,0);
sem_init(&s_servit,0,0);
sem_init(&s_sillo,0,0);
}

void fi () {
printf(" * * * Generacio de clients acabada * * * \n");
printf(" ***Fil principal obte estadistiques:\n");
printf("Fils client generats= %d amb %d atesos i %d no atesos\n"\
, cli_gen, cli_at, cli_no_at);
printf("El barber ha pogut descansar %d vegades\n", becades);
printf("*** FI DE SIMULACIO BARBER VERSIO %s\n", VERSIO);
}

int main (int argc, char * argv[] ) {
fprintf(stdout, "Barber %s\n", VERSIO);
fprintf(stdout, "*El barber obri la barberia\n");
fprintf(stdout, "***Cartell OBERT: ");
pthread_t fils_barber;
int i;
init_vars();
init_signals();
esta_obert= 1;
pthread_create(&fils_barber, NULL, barber, NULL);
sleep(1);
for (i=0; i<MAX_GEN_CLI; i++) {
pthread_create(&generador_clients[i],NULL, genera_client, (void *) &i);
sleep(1);
}
for (i=0; i<MAX_GEN_CLI; i++) {
pthread_join(generador_clients[i],NULL);//espera a que s'acabe el generador de clients
}
if (sillo_act < 0) {
fprintf(stderr, "Exitus Letalis {ACTIVAT}\n"\
);//text de control pa saber que ha tancat quan no hi ha clients i el barber dorm
exitus=1;
sem_post(&s_barber); //soltar semafor barber
} // despertar al barber dormilo
pthread_join(fils_barber,NULL); //espera a que acabe el barber
fi();
}
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder