Semaphores - C (project included, only small change needed)
Projeto1617_FaseFinal/Makefile
all: simulador monitor monitor: monitor.o gcc -Wall -g monitor.o -o monitor -lpthread monitor.o: monitor.c util.h unix.h gcc -c monitor.c simulador: simulador.o gcc -Wall -g simulador.o -o simulador -lpthread simulador.o: simulador.c util.h unix.h gcc -c simulador.c clean: rm *.o
Projeto1617_FaseFinal/monitor.c
#include <pthread.h> #include <string.h> #include "unix.h" #include "util.h" //apontador para o ficheiro onde será escrito o relatório da simulação FILE *relatorio; //variáveis globais para a estatística int num_fila_Piscina=0, num_fila_Toboga=0, num_Total_Clientes_Normais=0, num_Total_cli_Idoso_Crianca = 0, num_cli_normal=0, num_cli_Idoso_Crianca=0, desiste_espera=0, desiste_medo=0, num_utilizacoes_tbg1=0, num_utilizacoes_tbg2=0, num_utilizacoes_tbg3=0, num_utilizacoes_tbg4=0, num_utilizacoes_piscina=0, inicio_simulacao=0, fim_simulacao=0, soma_espera_normal=0, soma_espera_prio = 0, esperou_prio=0, esperou_normal=0; //variáveis globais para controlo de execução int corre=0, pausa=0; void mostra_estatistica() { if(corre && !pausa) printf(" 1. Estado atual: Simulacao a decorrer.\n"); else { if(pausa) printf(" 1. Estado atual: Simulação em pausa.\n"); else printf(" 1. Estado atual: Simulação terminada.\n"); } printf(" 2. Tamanho atual da fila de espera Tobogães: %d\n", num_fila_Toboga); printf(" 2. Tamanho atual da fila de espera Piscina: %d\n", num_fila_Piscina); //printf(" 3. Tamanho atual da fila de espera para Clientes Prioritários: %d\n", num_fila_crianca_idoso); //printf(" 4. Número atual de Carros: %d\n", num_carros); printf(" 5. Clientes Normais: %d\n", num_Total_Clientes_Normais); printf(" 6. Clientes Idosos/Criança: %d\n", num_Total_cli_Idoso_Crianca); printf(" 7. Total de Clientes: %d\n", num_Total_Clientes_Normais + num_Total_cli_Idoso_Crianca); printf(" 8. Desistências na Fila de espera: %d\n", desiste_espera); printf(" 9. Desistências Por medo: %d\n", desiste_medo); printf("10. Total de desistências: %d\n", desiste_espera + desiste_medo); printf("11. Número de Clientes que foram ao Tobogã 1: %d\n", num_utilizacoes_tbg1); printf("11. Número de Clientes que foram ao Tobogã 2: %d\n", num_utilizacoes_tbg2); printf("11. Número de Clientes que foram ao Tobogã 3: %d\n", num_utilizacoes_tbg3); printf("11. Número de Clientes que foram ao Tobogã 4: %d\n", num_utilizacoes_tbg4); printf("11. Número de Clientes que foram á piscina: %d\n", num_utilizacoes_piscina); if(esperou_normal) printf("12. Tempo médio de espera de Clientes Normais: %f minutos\n",(float)soma_espera_normal/(float)esperou_normal); else printf("12. Tempo médio de espera de Clientes Normais: 0 minutos\n"); if(esperou_prio) printf("13. Tempo médio de espera de Clientes Prioritários: %f minutos\n",(float)(soma_espera_prio/esperou_prio)); else printf("13. Tempo médio de espera de Clientes Prioritários: 0 minutos\n"); } //função que fica à escuta das mensagens do simulador void *escuta_comunicacao(void *arg) { int sockfd=*((int *) arg); int msg, tempo=0, num_comandos, id, tipo_cliente; char buffer[256],comando[20], atracao[20];//,utilizador[5],timestamp[11],; //ciclo que fica à espera de mensagens do simulador while(1) { if((msg=recv(sockfd, buffer, sizeof(buffer), 0)) <= 0) { if(msg < 0) perror("recv"); } else { buffer[msg]='\0'; fprintf(relatorio,"%s", buffer); num_comandos = sscanf(buffer,"%d %s %d %d", &tempo, comando, &id, &tipo_cliente); if(num_comandos>0) { if(!strcmp(comando,"INICIO")) { inicio_simulacao = tempo; } else if(!strcmp(comando,"CHEGADA_PISCINA")) { num_fila_Piscina++; if(tipo_cliente) num_Total_cli_Idoso_Crianca++; else num_Total_Clientes_Normais++; } else if(!strcmp(comando,"CHEGADA_TOBOGA")) { num_fila_Toboga++; num_Total_Clientes_Normais++; } else if(!strcmp(comando,"DESISTE_FILA_TOBOGA")) { desiste_espera++; num_fila_Toboga--; } else if(!strcmp(comando,"DESISTE_FILA_PISCINA")) { desiste_espera++; num_fila_Piscina--; } else if(!strcmp(comando,"EMBARQUE")) { switch(tipo_cliente){ case 1: num_utilizacoes_tbg1++; num_fila_Toboga--; break; case 2: num_utilizacoes_tbg2++; num_fila_Toboga--; break; case 3: num_utilizacoes_tbg3++; num_fila_Toboga--; break; case 4: num_utilizacoes_tbg4++; num_fila_Toboga--; break; } if(tipo_cliente) { soma_espera_prio += tempo; esperou_prio++; } else { soma_espera_normal += tempo; esperou_normal++; } } else if(!strcmp(comando,"EMBARQUE_PISCINA")) { num_utilizacoes_piscina++; num_fila_Piscina--; soma_espera_prio += tempo; esperou_prio++; } /*else if(!strcmp(comando,"ENTRA_EMBARQUE")) { if(tipo_cliente) { soma_espera_prio += tempo; esperou_prio++; } else { soma_espera_normal += tempo; esperou_normal++; } }*/ else if(!strcmp(comando,"DESISTE_EMBARQUE")) { desiste_medo++; } } } } return NULL; } //função principal do monitor int main(int argc, char *argv[]) { struct sockaddr_un serv_addr, cli_addr; int sockfd, servlen, newsockfd; int clilen=sizeof(cli_addr); char buffer[256]; char menu[512] = "----------------------------------\n| comandos disponiveis no monitor|\n----------------------------------\n| inicio - Comecar simulacao |\n| pausa - Pausar simulacao |\n| retomar - Retomar simulacao |\n| estado - Estado da simulacao |\n| sair - Sair do monitor |\n----------------------------------\n"; //Criacao do socket UNIX if((sockfd=socket(AF_UNIX, SOCK_STREAM, 0)) < 0) perror("cant open socket stream"); serv_addr.sun_family=AF_UNIX; strcpy(serv_addr.sun_path, UNIXSTR_PATH); servlen=strlen(serv_addr.sun_path)+sizeof(serv_addr.sun_family); unlink(UNIXSTR_PATH); if(bind(sockfd, (struct sockaddr *) &serv_addr, servlen) < 0) perror("cant bind local address"); listen(sockfd, 1); if((newsockfd=accept(sockfd, (struct sockaddr *) &cli_addr, &clilen)) < 0) perror("accept error"); //criacao da tarefa que ira tratar da comunicação tipo_cliente o simulador pthread_t thread; pthread_create(&thread, NULL, &escuta_comunicacao, &newsockfd); //Ciclo que espera pela informacao vinda da consola printf("%s",menu); unlink("relatorio.log"); relatorio=fopen("relatorio.log", "a"); do { fgets(buffer, sizeof(buffer), stdin); if(send(newsockfd, buffer, sizeof(buffer), 0) == -1) { perror("send"); exit(1); } if(!strcmp (buffer, "inicio\n")) { corre=1; pausa=0; } if(!strcmp (buffer, "pausa\n")) { pausa=1; printf("Simulacao em pausa - \"retomar\" para continuar\n"); } if(!strcmp (buffer, "retomar\n")) { pausa=0; } if(!strcmp (buffer, "estado\n")) { mostra_estatistica(); } } while(strcmp (buffer, "sair\n")); corre = 0; pausa = 0; printf("\nExecução terminou.\n\n"); mostra_estatistica(); fclose(relatorio); close(sockfd); return 0; }
Projeto1617_FaseFinal/sim.conf
INICIO_FINAL=0 TEMPO_SIMULACAO=3 TEMPO_MEDIO_CHEGADA_CLIENTES=1 PROB_DESISTE_ESPERA=10 PROB_DESISTE-ESPERA_IDOSO_CRIANCA=5 PROB_DESISTE_MEDO=5 PROB_DESISTE_MEDO_IDOSO_CRIANCA=2 TEMPO_VIAGEM=10 NUMERO_TOBOGAS=4 CAPACIDADE_UM_TOBOGA=1
Projeto1617_FaseFinal/simulador.c
/************************************************************************************************************ Sistemas Operativos - Projeto Pratico 2016/2017 - Simulacao de um Parque Aquático Docentes: Eduardo Marques, Luís Gaspar Alunos: ************************************************************************************************************/ #include <time.h> #include <stdlib.h> #include <semaphore.h> #include <string.h> #include <pthread.h> #include <signal.h> #include "unix.h" #include "util.h" /************************************************************************************************************ * variaveis globais * descricao: podem ser acedidas em qualquer momento e local durante a execucao do simulador ************************************************************************************************************/ sem_t zona_embarqueToboga_prio; sem_t zona_embarqueToboga; sem_t lugares_Piscina; sem_t tobogas_livres; sem_t sai_atracao; sem_t filaEsperaPiscina; sem_t sai_piscina; sem_t controla_toboga; sem_t pode_entrar_toboga; pthread_mutex_t mutex; int num_cliente, num_toboga_ocupados, fila_prio, carros_em_servico, num_toboga; int tempoEntra; int nr_toboga; char atracao [20]; time_t start; struct sockaddr_un serv_addr; int sockfd, servlen; //variaveis com informacao da configuracao int INICIO_FINAL, TEMPO_SIMULACAO, TEMPO_MEDIO_CHEGADA_CLIENTES, PROB_DESISTE_ESPERA, PROB_DESISTE_ESPERA_PRIO, PROB_DESISTE_MEDO, PROB_DESISTE_MEDO_PRIO, TEMPO_VIAGEM, NUMERO_TOBOGAS, CAPACIDADE_UM_TOBOGA; int corre=0,pausa=0,controlo_pausa; char printA[20] = "Toboga 1"; char printB[20] = "Toboga 2"; char printC[20] = "Toboga 3"; char printD[20] = "Toboga 4"; char printE[20] = "Piscina"; /************************************************************************************************************ * funcao: tarefa_cliente_IdosoCrianca * argumentos: ponteiro do tipo void * devolve: ponteiro do tipo void * descricao: comportamento de uma thread que representa um cliente idoso ou criança ************************************************************************************************************/ void *tarefa_cliente_IdosoCrianca(void *ptr) { pthread_detach(pthread_self()); //detach para devolver os recursos ao sistema -- pthread_self() retorna o id da tarefa int g, entra_espera; char ImprimeAtracao[20]; time_t temp_i; int tem_esp = rand()%10; // entre 0 e 10 minutos de espera char buffer_c[256]; sem_wait(&filaEsperaPiscina); //Se tiver lugar na fila de espera entra nesta, senão não faz nada pthread_mutex_lock(&mutex); //só uma tarefa é que pode entrar aqui, reserva os recuros - mais ngm pode aceder int num_cli_Idoso_Crianca = num_cliente++; fila_prio++; printf("O cliente %d chegou a fila de espera da piscina.\n", num_cli_Idoso_Crianca); sprintf(buffer_c, "%d CHEGADA_PISCINA %d 1\n", (int)time(0), num_cli_Idoso_Crianca); send(sockfd,buffer_c,sizeof(buffer_c),0); temp_i = time(0); if((int)(time(0) - temp_i) > tem_esp) { g = rand()%100; if(g <= PROB_DESISTE_ESPERA_PRIO) { if(tem_esp == 1) printf("O cliente %d desistiu da fila de espera da piscina ao fim de %d minuto a espera.\n", num_cli_Idoso_Crianca, tem_esp); else printf("O cliente %d desistiu da fila de espera da piscina ao fim de %d minutos a espera.\n", num_cli_Idoso_Crianca, tem_esp); sprintf(buffer_c, "%d DESISTE_FILA_PISCINA %d 1\n", (int)time(0), num_cli_Idoso_Crianca); send(sockfd,buffer_c,sizeof(buffer_c),0); fila_prio--; sem_post(&filaEsperaPiscina); pthread_mutex_unlock(&mutex); return NULL; } } //desistencia g = rand()%100; if(g <= PROB_DESISTE_MEDO_PRIO) { printf("O cliente %d desistiu porque ficou com medo.\n", num_cli_Idoso_Crianca); sprintf(buffer_c, "%d DESISTE_EMBARQUE\n", (int)time(0)); send(sockfd,buffer_c,sizeof(buffer_c),0); sem_post(&filaEsperaPiscina); pthread_mutex_unlock(&mutex); return NULL; } pthread_mutex_unlock(&mutex); //liberta os recursos, o cliente não desistiu da fila de espera - quer entrar sem_wait(&lugares_Piscina); //vericar se existe ou não lugares disponíveis na piscian (50) sem_post(&filaEsperaPiscina); //se existir sai da fila de espera da piscina e entra nesta pthread_mutex_lock(&mutex); // strcpy(ImprimeAtracao, atracao); printf("O cliente %d entrou na piscina.\n", num_cli_Idoso_Crianca); sprintf(buffer_c, "%d EMBARQUE_PISCINA %d %d\n", (int)(time(0)-temp_i), num_cli_Idoso_Crianca); send(sockfd,buffer_c,sizeof(buffer_c),0); pthread_mutex_unlock(&mutex); sem_wait(&sai_piscina); //semáforo para ver se o cliente quer ou não sair da piscina. Se não quiser fica aqui à espera pthread_mutex_lock(&mutex); printf("O cliente %d saiu da piscina.\n", num_cli_Idoso_Crianca); sprintf(buffer_c, "%d DESEMBARQUE %d %d\n", (int)time(0), num_cli_Idoso_Crianca); send(sockfd,buffer_c,sizeof(buffer_c),0); sem_post(&lugares_Piscina); pthread_mutex_unlock(&mutex); return NULL; } /************************************************************************************************************ * funcao: tarefa_cliente * argumentos: ponteiro do tipo void * devolve: ponteiro do tipo void * descricao: comportamento de uma thread que representa um cliente nao prioritario ************************************************************************************************************/ void *tarefa_cliente(void *ptr) { pthread_detach(pthread_self()); int g; char ImprimeAtracao[20]; time_t temp_i; char buffer_c[256]; int tempo_piscina = rand()%100; int tem_esp = rand()%10; // entre 0 e 10 minutos de espera int prob_ir_atracao = rand()%100; //para tratar da saida do cliente da piscina, assinala que ele quer sair da piscina if (tempo_piscina>=1 && tempo_piscina <= 15){ sem_post(&sai_piscina); }else{ if(prob_ir_atracao<= 80){ pthread_mutex_lock(&mutex); int num_cli = num_cliente++; printf("O cliente %d chegou a fila de espera dos tobogãs.\n", num_cli); sprintf(buffer_c, "%d CHEGADA_TOBOGA %d 0\n", (int)time(0), num_cli); send(sockfd,buffer_c,sizeof(buffer_c),0); pthread_mutex_unlock(&mutex); sem_wait(&zona_embarqueToboga); pthread_mutex_lock(&mutex); //desistencia por tempo if((int)(time(0) - temp_i) > tem_esp) { g = rand()%100; if(g <= PROB_DESISTE_ESPERA) { if(tem_esp == 1) printf("O cliente %d desistiu da fila de espera dos tobogãs ao fim de %d minuto a espera.\n", num_cli, tem_esp); else printf("O cliente %d desistiu da fila de espera dos tobogãs ao fim de %d minutos a espera.\n", num_cli, tem_esp); sprintf(buffer_c, "%d DESISTE_FILA_TOBOGA %d 0\n", (int)time(0), num_cli); send(sockfd,buffer_c,sizeof(buffer_c),0); sem_post(&zona_embarqueToboga); pthread_mutex_unlock(&mutex); return NULL; } } printf("O cliente %d entrou na zona de embarque dos tobogãs.\n",num_cli); sprintf(buffer_c, "%d ENTRA_EMBARQUE %d 0\n", time(0), num_cli); send(sockfd,buffer_c,sizeof(buffer_c),0); //desistencia por medo g = rand()%100; if(g <= PROB_DESISTE_MEDO) { printf("O cliente %d desistiu da fila de espera dos tobogãs porque ficou com medo.\n", num_cli); sprintf(buffer_c, "%d DESISTE_EMBARQUE\n", (int)time(0)); send(sockfd,buffer_c,sizeof(buffer_c),0); sem_post(&zona_embarqueToboga); pthread_mutex_unlock(&mutex); return NULL; } pthread_mutex_unlock(&mutex); sem_wait(&tobogas_livres); sem_post(&zona_embarqueToboga); //assinala que ficou um lugar vago na zona de embarque dos tobogas pthread_mutex_lock(&mutex); // if(nr_toboga >=0 && nr_toboga<4) // nr_toboga++; // strcpy(ImprimeAtracao, atracao); printf("O cliente %d entrou no tobogã %d.\n", num_cli, nr_toboga); //O cliente entrou no tobogã X sprintf(buffer_c, "%d EMBARQUE %d %d\n", (int)(time(0)-temp_i), num_cli, nr_toboga); send(sockfd,buffer_c,sizeof(buffer_c),0); num_toboga_ocupados++; pthread_mutex_unlock(&mutex); sem_wait(&sai_atracao); //para já ver se todos sairam pthread_mutex_lock(&mutex); printf("O cliente %d saiu da zona de tobogãs.\n", num_cli); sprintf(buffer_c, "%d DESEMBARQUE %d %d\n", (int)time(0), num_cli, nr_toboga); send(sockfd,buffer_c,sizeof(buffer_c),0); pthread_mutex_unlock(&mutex); } else{ sem_wait(&filaEsperaPiscina); //Se tiver lugar na fila de espera entra nesta, senão não faz nada pthread_mutex_lock(&mutex); //só uma tarefa é que pode entrar aqui, reserva os recuros - mais ngm pode aceder int num_cli_Idoso_Crianca = num_cliente++; fila_prio++; printf("O cliente %d chegou a fila de espera da piscina.\n", num_cli_Idoso_Crianca); sprintf(buffer_c, "%d CHEGADA_PISCINA %d 1\n", (int)time(0), num_cli_Idoso_Crianca); send(sockfd,buffer_c,sizeof(buffer_c),0); //temp_i = time(0); if((int)(time(0) - temp_i) > tem_esp) { g = rand()%100; if(g <= PROB_DESISTE_ESPERA_PRIO) { if(tem_esp == 1) printf("O cliente %d desistiu da fila de espera da piscina ao fim de %d minuto a espera.\n", num_cli_Idoso_Crianca, tem_esp); else printf("O cliente %d desistiu da fila de espera da piscina ao fim de %d minutos a espera.\n", num_cli_Idoso_Crianca, tem_esp); sprintf(buffer_c, "%d DESISTE_FILA_PISCINA %d 1\n", (int)time(0), num_cli_Idoso_Crianca); send(sockfd,buffer_c,sizeof(buffer_c),0); fila_prio--; sem_post(&filaEsperaPiscina); pthread_mutex_unlock(&mutex); return NULL; } } //desistencia g = rand()%100; if(g <= PROB_DESISTE_MEDO_PRIO) { printf("O cliente %d desistiu porque ficou com medo.\n", num_cli_Idoso_Crianca); sprintf(buffer_c, "%d DESISTE_EMBARQUE\n", (int)time(0)); send(sockfd,buffer_c,sizeof(buffer_c),0); sem_post(&filaEsperaPiscina); pthread_mutex_unlock(&mutex); return NULL; } pthread_mutex_unlock(&mutex); //liberta os recursos, o cliente não desistiu da fila de espera - quer entrar sem_wait(&lugares_Piscina); //vericar se existe ou não lugares disponíveis na piscian (50) sem_post(&filaEsperaPiscina); //se existir sai da fila de espera da piscina e entra nesta pthread_mutex_lock(&mutex); // strcpy(ImprimeAtracao, atracao); printf("O cliente %d entrou na piscina.\n", num_cli_Idoso_Crianca); sprintf(buffer_c, "%d EMBARQUE_PISCINA %d %d\n", (int)(time(0)-temp_i), num_cli_Idoso_Crianca); send(sockfd,buffer_c,sizeof(buffer_c),0); pthread_mutex_unlock(&mutex); sem_wait(&sai_piscina); //semáforo para ver se o cliente quer ou não sair da piscina. Se não quiser fica aqui à espera pthread_mutex_lock(&mutex); printf("O cliente %d saiu da piscina.\n", num_cli_Idoso_Crianca); sprintf(buffer_c, "%d DESEMBARQUE %d %d\n", (int)time(0), num_cli_Idoso_Crianca); send(sockfd,buffer_c,sizeof(buffer_c),0); sem_post(&lugares_Piscina); pthread_mutex_unlock(&mutex); return NULL; } } return NULL; } /************************************************************************************************************ * funcao: tarefa_atracao * argumentos: ponteiro do tipo void * devolve: ponteiro do tipo void * descricao: comportamento de uma thread que representa um cliente prioritario ************************************************************************************************************/ void *tarefa_atracao(void *ptr) { pthread_detach(pthread_self()); int i; char printAtracao[20]; char buffer_c[256]; time_t hora_partida, hora_i; char variavel[20] = "atracao"; nr_toboga ++; void inicia_viagem() { printf("O tobogã %d começou.\n", nr_toboga); sprintf(buffer_c, "%d ARRANQUE %d\n", (int)time(0), nr_toboga); send(sockfd,buffer_c,sizeof(buffer_c),0); hora_partida = time(0); pthread_mutex_unlock(&mutex); while((int)(time(0) - hora_partida) < TEMPO_VIAGEM); // tempo de viagem pthread_mutex_lock(&mutex); printf("O tobogã %d terminou e está disponível aos proximos utilizadores.\n", nr_toboga); sprintf(buffer_c, "%d FINAL_VIAGEM %d\n", (int)time(0), nr_toboga); send(sockfd,buffer_c,sizeof(buffer_c),0); sem_post(&sai_atracao); //diz que todos os clientes sairam (1) num_toboga_ocupados= 0; // for(i=0;i<NUMERO_TOBOGAS; i++){ // sem_post(&tobogas_livres); //indica que os tobogãs vão estar vazios // } nr_toboga = 0; } while(1) { pthread_mutex_lock(&mutex); printf("O tobogã %d está disponível.\n", nr_toboga); sprintf(buffer_c, "%d DISPONIVEL %d\n", (int)time(0), nr_toboga); send(sockfd,buffer_c,sizeof(buffer_c),0); sem_post(&tobogas_livres); pthread_mutex_unlock(&mutex); int i; //sem_getvalue(&zona_embarqueToboga, &i); hora_i = time(0); if(time(0) > start + TEMPO_SIMULACAO) { usleep(100000); pthread_mutex_lock(&mutex); if(num_toboga_ocupados == 0) { printf("O parque ja fechou e nao tem clientes em espera.\n"); printf("O tobogã %d vai ser limpo.\n", nr_toboga); carros_em_servico--; pthread_mutex_unlock(&mutex); return NULL; } printf("O tobogã %d comecou.\n", nr_toboga); sprintf(buffer_c, "%d ARRANQUE %d\n", (int)time(0), nr_toboga); send(sockfd,buffer_c,sizeof(buffer_c),0); hora_partida = time(0); pthread_mutex_unlock(&mutex); while((int)(time(0) - hora_partida) < TEMPO_VIAGEM); // tempo de viagem pthread_mutex_lock(&mutex); printf("O tobogã %d fechou.\n", nr_toboga); sprintf(buffer_c, "%d FINAL_VIAGEM %d\n", (int)time(0), nr_toboga); send(sockfd,buffer_c,sizeof(buffer_c),0); for(i = 0; i < NUMERO_TOBOGAS; i++) sem_post(&sai_atracao); } else { while(num_toboga_ocupados < NUMERO_TOBOGAS && time(0) < start + TEMPO_SIMULACAO); //enquanto todos os tobogãs não estiverem ocupados não vai iniciar a sua atividade //é incrementado na tarefa clienteNormal pthread_mutex_lock(&mutex); if(num_toboga_ocupados == NUMERO_TOBOGAS) //se todos os tobogãs estiverem atualmente ocupados, vai iniciar a sua atividade (de todos) { pthread_mutex_unlock(&mutex); usleep(100000); pthread_mutex_lock(&mutex); inicia_viagem(); } else { pthread_mutex_unlock(&mutex); usleep(100000); pthread_mutex_lock(&mutex); if(num_toboga_ocupados == 0) { printf("O parque ja fechou e nao tem clientes em espera.\n"); printf("O tobogã %d vai ser arrumado.\n", nr_toboga); carros_em_servico--; pthread_mutex_unlock(&mutex); return NULL; } inicia_viagem(); } } pthread_mutex_unlock(&mutex); } return NULL; } //Funcao que trata dos pedidos vindos do Monitor void *recebe_comandos_monitor(void *arg) { struct sockaddr_un cli_addr; int done, n, id; int sockfd=*((int *) arg), clilen=sizeof(cli_addr); char buffer[256]; //Ciclo que fica a espera dos pedidos dos Monitor, para lhe dar resposta adequada while(1) { done=0; if((n=recv(sockfd, buffer, sizeof(buffer), 0)) <= 0) { if(n < 0) perror("recv error"); done=1; } buffer[n]='\0'; if(!strcmp(buffer, "termina\n")) { corre=0; exit(1); } else { if(!strcmp(buffer, "inicio\n")) corre = 1; if(!strcmp(buffer, "pausa\n")) pausa = 1; if(!strcmp(buffer, "retomar\n")) pausa = 0; } } return NULL; } int main(int argc, char *argv[]) { srand(time(NULL)); num_cliente=1; //atracao = 1; num_toboga_ocupados = 0; fila_prio = 0; if(argc<2) { printf("Falta o ficheiro de configuração. Não é possível continuar."); return 1; } else { //interpretacao do ficheiro de configuraçao int *conf = leitura_configuracao(argv[1]); INICIO_FINAL = conf[0]; TEMPO_SIMULACAO = conf[1]; TEMPO_MEDIO_CHEGADA_CLIENTES = conf[2]; PROB_DESISTE_ESPERA = conf[3]; PROB_DESISTE_ESPERA_PRIO = conf[4]; PROB_DESISTE_MEDO = conf[5]; PROB_DESISTE_MEDO_PRIO = conf[6]; TEMPO_VIAGEM = conf[7]; NUMERO_TOBOGAS = conf[8]; CAPACIDADE_UM_TOBOGA = conf[9]; // Inicializar semáforos sem_init (&zona_embarqueToboga, 0, 10); sem_init (&pode_entrar_toboga, 0, 0); sem_init (&lugares_Piscina, 0, 50); sem_init (&sai_atracao, 0, 0); sem_init (&tobogas_livres, 0, 0); //semáforo para indicar se os tobogãs estão (0) ou não vazios (1) sem_init (&filaEsperaPiscina,0,10); sem_init (&sai_piscina,0,0); sem_init (&controla_toboga,0,1); //criacao do socket e ligação if((sockfd=socket(AF_UNIX, SOCK_STREAM, 0)) < 0) perror("Simulador: cant open socket stream"); serv_addr.sun_family=AF_UNIX; strcpy(serv_addr.sun_path, UNIXSTR_PATH); servlen=strlen(serv_addr.sun_path)+sizeof(serv_addr.sun_family); if(connect(sockfd, (struct sockaddr *) &serv_addr, servlen) < 0) perror("connect error"); //Criacao da tarefa que ira tratar dos pedidos enviados pelo Monitor pthread_t thread; pthread_create(&thread, NULL, &recebe_comandos_monitor, &sockfd); while(!corre); int i, r, h; char buffer[256]; carros_em_servico = CAPACIDADE_UM_TOBOGA; start = time(0); sprintf(buffer, "%d INICIO\n", (int)start); send(sockfd,buffer,sizeof(buffer),0); TEMPO_SIMULACAO *= 60; //thread atracao for(i = 0; i < 4; i++) { num_toboga=1; pthread_create(&thread, NULL, &tarefa_atracao, &sockfd); //usleep(10000); } while((int)(time(0) - start) < TEMPO_SIMULACAO) { r = rand()%100; if (r <= 50) { //Criacao da tarefa de um cliente prioritário pthread_create(&thread, NULL, &tarefa_cliente_IdosoCrianca, &sockfd); } else { //Criacao da tarefa de um cliente normal pthread_create(&thread, NULL, &tarefa_cliente, &sockfd); } r = rand()%1; h = rand()%3; h = h * 100000; if(r == 0) h = 0 - h; usleep((TEMPO_MEDIO_CHEGADA_CLIENTES*1000000) + h); if(pausa) { pthread_mutex_lock(&mutex); controlo_pausa = 1; } while(pausa); if(controlo_pausa) { pthread_mutex_unlock(&mutex); controlo_pausa = 0; } } while(carros_em_servico>0); printf("\nO parque já fechou e não existem mais clientes em espera.\n"); printf("\nSimulação terminada.\n"); sprintf(buffer,"%d FIM \n",(int) time(0)); send(sockfd,buffer,sizeof(buffer),0); while(corre); close(sockfd); } return 0; }
Projeto1617_FaseFinal/unix.h
#include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define UNIXSTR_PATH "./s.unixstr" #define UNIXDG_PATH "/tmp/s.unixdgx" #define UNIXDG_TMP "/tmp/dgXXXXsdsXX"
Projeto1617_FaseFinal/util.h
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> //#define MAXLINE 512 int *leitura_configuracao(char *file) { int *a = (int *)malloc(sizeof(int) * 10); FILE *fp = fopen (file, "r"); if(fp == NULL ) { printf("Nao e possivel abrir o ficheiro de configuracao.\n"); abort(); } int num, i=0; char name[100], buff[500]; while (fgets( buff, sizeof buff, fp) != NULL) { if(sscanf(buff, "%[^=]=%d", name, &num) == 2) a[i++]=num; } fclose(fp); return a; }