21
i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de elevadores Sistemas Operativos Trabalho Efectuado por: Paulo Ferreira: [email protected] Pedro Mendes: [email protected] Grupo 5 Turma 3

Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

Embed Size (px)

Citation preview

Page 1: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

i

Licenciatura em Engenharia Informática e Computação

Simulador de funcionamento de elevadores Sistemas Operativos

Trabalho Efectuado por:

Paulo Ferreira: [email protected]

Pedro Mendes: [email protected]

Grupo 5

Turma 3

Page 2: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

ii

Resumo

Neste trabalho pretende-se simular um sistema de elevadores de um prédio e os seus utilizadores, recorrendo a threads.

Page 3: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

iii

Índice de Conteúdos

1 Descrição do Problema ....................................................................................................................2

2 Funcionalidades Implementadas ..................................................................................................3

3 Arquitectura Global ...........................................................................................................................4 3.1 Fluxograma do thread utilizadores........................................................................................................... 4 3.2 Fluxograma do thread elevadores .......................................................................................................... 5 3.3 Fluxograma do thread Main .................................................................................................................... 6

4 Algoritmo dos Threads......................................................................................................................7

5 Testes.............................................................................................................................................10

6 Código em Anexo ....…………………………………………………………..…………………………………………12

Page 4: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

1

Page 5: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

2

1 Descrição do problema

O sistema de elevadores a implementar tem algumas limitações pedidas, como por exemplo o ciclo de vida dos utilizadores é muito simples e sempre igual: sequencialmente chegam ao prédio, apanham o elevador para um andar (escolhido aleatoriamente) onde esperam um certo tempo para depois voltarem a sair pelo andar 0 por onde tinham entrado. Temos derivado desta mesma limitação, a simplificação do ciclo de vida dos elevadores, pois apenas têm um botão em cada andar dado que eles só necessitam de largar as pessoas e ir busca-las novamente para o piso 0.

O sistema que implementámos, baseia-se totalmente nestes pressupostos, embora como extra o tenhamos aproximado de um caso mais geral, mais próximo do pedido para um elevador normal.

Page 6: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

3

2 Funcionalidades implementadas

Implementámos todas as funcionalidades pedidas e repensámos o funcionamento proposto para melhorar o desempenho do sistema e aproximar ao caso geral do funcionamento. Por exemplo o algoritmo de escolha do próximo destino do elevador foi melhorado e será explicado na secção seguinte.

Page 7: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

4

Atribui aleatóriamente o

piso de destino da pessoa

Espera por um elevador que a vai transportar ate ao

piso de destino

Entra no elevador, selecciona o piso de destino, espera

que chegue a esse piso e sai do

elevador

Passa o tempo passado por parâmetro na

consola no piso

Chama um elevador para

descer

Aguarda por um elevador que a vai transpostar até ao

piso 0

Entra no elevador , selecciona o piso

0 ,espera que chegue ao piso e sai do elevador

Devolve , ao thread principal o tempo máximo de

espera e de viagem e as suas

médias

Fluxograma thread

utilizador

3 Arquitectura global

3.1 Fluxograma thread utilizadores

Page 8: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

5

3.2 Fluxograma thread elevador

Page 9: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

6

Cria um conjunto de variáveis

partilhadas como o estado do botão

de chamada de cada piso, o

estado da porta de cada um dos elevadores, o

painel dos botões existentes no

interior do elevador, os

mux’s, pisos a serem atendidos por um elevador

Cria um thread por cada elevador, passando lhe

como argumento a sua identificação

Cria um thread por cada

utilizador,com um intervalo entre a criação de dois

threads consecutivos

especificado na linha de

comandos, passando lhe

como argumento a sua identificação

No final da simulação,esperar

por todos os threads e imprimir

os dados estatísticos

Testa a condição de terminação do

programa

3.3 Fluxograma do Main Thread

Page 10: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

7

4 Algoritmo dos threads (pseudo-código)

Main

Verifica os argumentos inseridos pelo utilizador e se não forem os correctos da mensagem de USAGE.

Inicia a Semente do random.

Chama a função de init_building, onde são iniciadas todas as estruturas de dados e os mux’s para cada um deles:

- portaElevadores: Array de Arrays de inteiros que dá informação das portas em cada piso(1 aberta 0 fechada)

-botaoChamada: Array de inteiros que dá informação sobre o botão de chamada em cada piso (1 activado 0 desactivado)

-painelChamada : Array de Arrays de inteiros que dá informação sobre os botões dos pisos em cada elevador(1 activado 0 desactivado)

-pisoAtendido: Array de Arrays de inteiros que dá informação sobre se algum elevador está já a dirigir para o piso e o id do mesmo.

Chama a função de criação dos threads elevador com o argumento id.

Chama a função de criação dos threads pessoa com o argumento id.

Chama a função de finish() que espera pelo final de todos os threads recebe o valor de retorno (estrutura estatistica que contêm toda informação para as estatisticas) e apresenta a estatística.

Pessoa

Cria estrutura pessoa, com destino aleatório;

Início da contagem do primeiro tempo de espera;

Carrega no botão para chamar um elevador (botão = 1);

Faz Lock ao array que contêm informação sobre as portas dos elevadores nesse piso.

Procura um elevador com a porta aberta;

Se não encontrar porta aberta{

Quando o elevador chega (recebe broadcast) verifica se o broadcast foi enviado por um elevador do seu piso, se sim desbloqueia o Lock às portas desse piso e procura a porta aberta ;

}

Fim da contagem do primeiro tempo de espera;

Apanha esse elevador;

Início da contagem do primeiro tempo de viagem;

Entra no elevador;

Carrega no botão do destino;

Cada vez que a porta se abre (broadcast) verifica se é o seu destino e, caso seja, sai;

Page 11: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

8

Fim da contagem do primeiro tempo de viagem;

Trabalha (espera tempo)

Altera destino para 0 (saída)

Carrega no Botão para Chamar um elevador(botão = 1)

Início da contagem do segundo tempo de espera

Procura um elevador com a porta aberta, se o encontrar, entra;

Caso não o encontre

Quando o elevador chega (recebe broadcast) procura a porta aberta

Se não houver nenhuma, volta ao passo em que carrega no botão

Fim da contagem do segundo tempo de espera;

Início da contagem do segundo tempo de viagem;

Entra no elevador;

Carrega no botão do destino;

Cada vez que a porta se abre (broadcast) verifica se é o seu destino e, caso seja, sai;

Fim da contagem do segundo tempo de viagem;

Calcula tempos médio e máximo de espera e de viagem e guarda-os numa estrutura;

Acaba thread, devolve estrutura com os tempos.

Elevador

Cria a estrutura Elevadores;

Abre a porta do Elevador

Espera o tempo da porta e enquanto não tiver botões no painel de Chamada activados verifica se têm botões de pisos superiores activados. Se não tiver volta a repetir o processo; Se tiver informa que está a dirigir-se para esse piso fecha a porta e altera o seu destino.

Se tiver um painel de chamada activado fecha a porta e altera o seu destino segundo o botão do painel de chamada activado mais perto.

Em cada piso, verifica se chegou ao piso desejado, se não chegou, verifica se o botão desse piso está accionado. Se estiver altera o seu estado para parado e (lança broadcast)abre a porta. Espera o tempo da porta aberta e volta a fechar. Volta a verificar o painel de Chamada, a partir do piso em que estava e segundo a direcção anterior. Se têm um destino mais perto que o anterior altera o seu destino para este.

Se o piso em que está for igual ao piso de destino (lança broadcast) abre a porta, altera o seu estado para parado e espera o tempo com a porta aberta. Verifica se têm mais chamadas no painel, na direcção que corria, se tiver altera o seu destino e fecha a porta. Se não tiver

Page 12: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

9

verifica se existe algum botão de chamada nos pisos superiores/inferiores (segundo a sua anterior direcção). Se tiver altera o seu destino, fecha a porta e avisa que está encarregue de ir para esse piso. Se não estiver repete o ultimo procedimento com a direcção contrária do anterior. Se este ultimo também falhar volta a repetir este processo todo com a excepção da abertura da porta(e do seu respectivo broadcast).

Verifica a condição finished e se esta for falsa, continua todo o procedimento, se este for true termina o thread

Page 13: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

10

5 Testes

Fizemos variados testes, desde testes básicos de simples erro de usage, até testes exagerados como por exemplo 300 utilizadores 3 elevadores 20 pisos ou mesmo uma pequena simulação do Empire State Building com 300 utilizadores (70 elevadores 102 pisos).

Não detectamos qualquer tipo de erro após efectuar os testes finais. Fica em baixo imagens das estatísticas de alguns destes testes:

Figura 1 – Estatísticas do teste com o seguinte comando “simelev 102 70 300 1 1 1 5 3”

Page 14: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

11

Figura 2 – Estatísticas do teste com o seguinte comando “simelev 300 3 20 1 1 1 5 3”

Page 15: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

12

6 - Código Anexo /******************************************************************************************************************* 2º Trabalho de Sistemas Operativos Simulador de Sistema de Elevadores ******************************************************************************************************************* Autores: - Paulo Ferreira ei02005 - Pedro Daniel ei01108 */ #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <sys/time.h> #include <errno.h> #include <time.h> #define FALSE 0 #define TRUE 1 #define PARADO 0 #define CIMA 1 #define BAIXO -1 //################################ Prototipos de funções############################################################## void init_building(void); //Elevador void init_elevador(void); void init_people(int,int); void finish(void); int next_dest(int, int, int, int); void open_door(int,int); void close_door(int,int); void press_button(int); int wait(int,int); void get_in(int,int,int,int); void go_on(int,int,int); void get_out(int,int,int); //################################ Fim Prototipos##################################################################### //################################ ESTRUTURAS ##################################################################### typedef struct { int n_elev;//nº do elevador int pisoActual;// piso em que o elevador se encontra int pisoChegada;//piso de destino do elevador int direccao;//Cima,Baixo,Parado int direccao_ant; }Elevador; typedef struct { int n_pess; int pisoDestino; int elev; }Pessoa; typedef struct { float tempoMedioEspera; float tempoMedioViagem; int tempoMaximoEspera; int tempoMaximoViagem; }Estatistica; //####################### FIM ESTRUTURAS ########################################################################## //################################ Threads ######################################################################## void *thr_elevador(void *params); void *thr_pessoa(void *arg); pthread_mutex_t *muxPortaElevadores; pthread_mutex_t *muxPainelChamada; pthread_mutex_t *muxBotaoChamada; pthread_mutex_t *muxPisoAtendido;

Page 16: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

13

pthread_cond_t elev_cond; //################################ Fim Threads ################################################################ //################################ Globais #################################################################### //Variaveis de representação do estado do edificio int **portaElevadores;//Vector que contem Vectores em que o id do elevador corresponde a sua posição no vector e que contêm Estado da Porta(x portas por piso) (FALSE se Fechado TRUE se ABERTO int *botaoChamada;//vector que contem o estado de chamada do botao, a posição de cada estado corresponde ao piso int **painelChamada;//vector que contem vectores de booleanos que indicam o piso accionado (um por elevador) int **pisoAtendido; //Global para puder pesquisar o painel de controlo do elevador int num_floors; int num_elevators; int num_people; int speed; int waitt; int workt; //Variavel de controlo de final de simulação int finished=0; pthread_t *elevator_t; pthread_t *people_t; //################################ Fim Globais ################################################################ /*************************************************************************************** PROGRAMA PRINCIPAL ***************************************************************************************/ int main(int argc, char *argv[]) { //Threads ID's -> Servem para identificação de cada um dos threads //pthread_t *tid; //Teste de USAGE!!! if(argc != 9) { printf ("USAGE : simelev nfloors nelev nusers speed waitt intmin intmax workt\n"); return -1; } srand(time(NULL)); // declaração de variáveis // o espaço para algumas das variáveis deverá ser alocado dinamicamente num_floors=atoi(argv[1]); num_elevators=atoi(argv[2]); num_people=atoi(argv[3]); speed=atoi(argv[4]); waitt=atoi(argv[5]); int intmin=atoi(argv[6]); int intmax=atoi(argv[7]); workt=atoi(argv[8]); if(intmax<intmin) { printf("USAGE: intmin tem de ser inferior a intmax!!\n"); return -1; } //int esperaPessoa=(int) argv[2];; init_building(); init_elevador(); init_people(intmin,intmax); finish(); pthread_exit(NULL);//Espera pela terminação dos seus THREADS; } void init_building() { int i; pthread_cond_init (&elev_cond,NULL); portaElevadores = calloc(num_floors, sizeof(int*)); for(i=0; i<num_floors; i++) portaElevadores[i]= calloc(num_elevators , sizeof(int)); painelChamada = calloc(num_elevators,sizeof(int*)); for(i=0; i<num_elevators; i++) painelChamada[i]= calloc(num_floors , sizeof(int)); //portaPisos = (int*) malloc(num_floors*sizeof(int)); //botaoChamada = (int*) ca printf("Elevador %d a subir do piso %d para o piso %d\n",elev.n_elev,elev.pisoActual,elev.pisoChegada);lloc (num_floors, sizeof(int));

Page 17: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

14

botaoChamada = (int*) calloc (num_floors, sizeof(int)); pisoAtendido = calloc (num_floors, sizeof(int*)); for(i=0; i<num_floors;i++) { pisoAtendido[i] = calloc (2, sizeof(int)); } muxPisoAtendido = calloc (num_floors,sizeof(pthread_mutex_t)); muxPortaElevadores = calloc (num_floors,sizeof(pthread_mutex_t)); muxBotaoChamada = calloc (num_floors,sizeof(pthread_mutex_t)); for(i=0;i<num_floors;i++) { pthread_mutex_init (&(muxPortaElevadores[i]),NULL); pthread_mutex_init (&(muxBotaoChamada[i]),NULL); } muxPainelChamada = (pthread_mutex_t*) malloc (num_elevators*sizeof(pthread_mutex_t)); for(i=0;i<num_elevators;i++) { pthread_mutex_init (&(muxPainelChamada[i]),NULL); } } void init_elevador() { //pthread_t elevator_t[num_elevators]; elevator_t = calloc(num_elevators,sizeof(pthread_t)); int i; for(i=0;i<num_elevators;i++) { pthread_create(&elevator_t[i], NULL, thr_elevador, (void *) i);// foi usado o "truque dos acetatos passamos o valor do argumento em vez de se passar o seu endereço" } } void init_people(int intmin,int intmax) { //pthread_t people_t[num_people]; people_t = calloc(num_people,sizeof(pthread_t)); int i; int esperaPessoa; for (i=0;i<num_people;i++) { printf("[CRIADA] Pessoa %d foi criada\n", i); pthread_create(&people_t[i], NULL, thr_pessoa, (void *) i); esperaPessoa = rand()%(intmax+1-intmin)+intmin; //printf("Tempo de espera da pessoa criada = %d\n",esperaPessoa); //printf("Tempo maximo de espera para pessoa criada = %d\n",intmax); sleep(esperaPessoa); } } void finish() { int i; void *tempoEspera[num_people-1]; Estatistica stat; //float tempoEsperaMedio; for(i=0;i<num_people;i++) { pthread_join(people_t[i],&tempoEspera[i]); //tempoEsperaTotal=tempoEsperaTotal + *(Estatistica *) tempoEspera[i]; //stat = *(Estatistica *) tempoEspera[i]; //printf("[Acabou] A pessoa %d com um tempo de espera por elevadores medio de %f segundos!!!\n",i+1,stat.tempoMedioEspera); } finished=1; for(i=0;i<num_people;i++) { pthread_join(elevator_t[i],NULL); } //Apresenta a estatistica da simulação printf("\n"); printf("########################## ESTATISTICAS ##########################\n"); printf("Pessoa\tTempo Medio de Espera\tTempo Medio de Viagem\tTempo Maximo de Espera\tTempo Maximo de Viagem\n"); float tempoMedioEsperaTotal=0; float tempoMedioViagemTotal=0; float tempoMaximoEsperaTotal=0; float tempoMaximoViagemTotal=0; for(i=0;i<num_people;i++) { stat = *(Estatistica *) tempoEspera[i]; printf("%d \t%f \t%f \t%d \t%d\n", i,stat.tempoMedioEspera,stat.tempoMedioViagem,stat.tempoMaximoEspera,stat.tempoMaximoViagem); tempoMedioEsperaTotal= (tempoMedioEsperaTotal+stat.tempoMedioEspera); tempoMedioViagemTotal=(tempoMedioViagemTotal+stat.tempoMedioViagem);

Page 18: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

15

tempoMaximoEsperaTotal=(tempoMaximoEsperaTotal + stat.tempoMaximoEspera); tempoMaximoViagemTotal=(tempoMaximoViagemTotal + stat.tempoMaximoViagem); } printf("Media:\t%f \t%f \t%f \t%f\n", tempoMedioEsperaTotal/num_people,tempoMedioViagemTotal/num_people,tempoMaximoEsperaTotal/num_people,tempoMaximoViagemTotal/num_people); printf("##################### Fim das ESTATISTICAS #######################\n"); /*for(i=0;i<num_people;i++) { }*/ } /********************************************************************************************************************* ELEVADOR *********************************************************************************************************************/ void *thr_elevador(void *arg) { Elevador elev; int id; id=(int) arg; elev.n_elev = id+1; elev.pisoActual=0; elev.pisoChegada=0; elev.direccao=PARADO; elev.direccao_ant=PARADO; //sleep(2); /*pthread_mutex_lock(&muxPortaElevadores[elev.pisoActual]); printf("Estado da porta do elevador nº %d: %d\n", elev.n_elev, portaElevadores[elev.pisoActual][id]); pthread_mutex_unlock(&muxPortaElevadores[elev.pisoActual]);*/ //int i; while(1) { //printf("Varios YEHS YEHHHH!!!\n"); pthread_mutex_lock(&muxPainelChamada[id]); pthread_mutex_lock(&muxBotaoChamada[elev.pisoActual]); pthread_mutex_lock(&muxPisoAtendido[elev.pisoActual]); elev.pisoChegada = next_dest(id ,elev.pisoActual,elev.direccao,elev.direccao_ant); pthread_mutex_unlock(&muxPisoAtendido[elev.pisoActual]); pthread_mutex_unlock(&muxBotaoChamada[elev.pisoActual]); pthread_mutex_unlock(&muxPainelChamada[id]); if(elev.pisoActual == elev.pisoChegada) { if (elev.direccao != PARADO) { printf("\t[PARAR] Elevador %d parou no piso %d\n",elev.n_elev,elev.pisoActual); elev.direccao_ant=elev.direccao; elev.direccao=PARADO; } open_door(id,elev.pisoActual); sleep(waitt);//tempo de espera com a porta aberta } else if(elev.pisoActual < elev.pisoChegada) { if(elev.direccao != CIMA) { elev.direccao=CIMA; close_door(id,elev.pisoActual); printf("\t[SUBIR] Elevador %d a subir do piso %d para o piso %d\n",elev.n_elev,elev.pisoActual,elev.pisoChegada); } elev.pisoActual++; sleep(speed);//tempo de espera entre pisos }else { if(elev.direccao != BAIXO) { elev.direccao=BAIXO; close_door(id,elev.pisoActual); printf("\t[DESCER] Elevador %d a descer do piso %d para o piso %d\n",elev.n_elev,elev.pisoActual,elev.pisoChegada); } elev.pisoActual--; sleep(speed);//tempo de espera entre pisos } if(finished==1) return NULL; } return NULL; } int next_dest(int id_Elevador, int pisoActual, int direccao, int direccao_ant)

Page 19: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

16

{ int i; if(direccao == PARADO || direccao == CIMA) { //Verifica Para Pisos superiores if(direccao == PARADO && direccao_ant == BAIXO ) { int k; for(k=pisoActual;k>=0;k--) { if(painelChamada[id_Elevador][k] == TRUE) return k; if(botaoChamada[k] == TRUE && ((pisoAtendido[k][0] == FALSE) || (pisoAtendido[k][0] == TRUE && pisoAtendido[k][1] == id_Elevador ))) { pisoAtendido[k][0] = TRUE; pisoAtendido[k][1] = id_Elevador; return k; } } } for (i=pisoActual;i<num_floors;i++) { if(painelChamada[id_Elevador][i] == TRUE ) return i; if(botaoChamada[i] == TRUE && ((pisoAtendido[i][0] == FALSE) || (pisoAtendido[i][0] == TRUE && pisoAtendido[i][1] == id_Elevador ))) { pisoAtendido[i][0] = TRUE; pisoAtendido[i][1] = id_Elevador; return i; } } //Se nao encontrar verifica para pisos inferiores for (i=pisoActual;i>=0;i--) { if(painelChamada[id_Elevador][i] == TRUE) return i; if(botaoChamada[i] == TRUE && ((pisoAtendido[i][0] == FALSE) || (pisoAtendido[i][0] == TRUE && pisoAtendido[i][1] == id_Elevador ))) { pisoAtendido[i][0] = TRUE; pisoAtendido[i][1] = id_Elevador; return i; } } } if(direccao==BAIXO) { //Verifica Para Pisos inferiores for (i=pisoActual;i>=0;i--) { if(painelChamada[id_Elevador][i] == TRUE) return i; if(botaoChamada[i] == TRUE && ((pisoAtendido[i][0] == FALSE) || (pisoAtendido[i][0] == TRUE && pisoAtendido[i][1] == id_Elevador ))) { pisoAtendido[i][0] = TRUE; pisoAtendido[i][1] = id_Elevador; return i; } } //Se nao encontrar verifica para pisos superiores // for (i=pisoActual;i<num_floors;i++) // { // if(painelChamada[id_Elevador][i] == TRUE) // return i; // if(botaoChamada[i] == TRUE) // return i; // // } } return pisoActual; } void open_door(int id,int pisoActual) { pthread_mutex_lock(&muxPortaElevadores[pisoActual]); if(portaElevadores[pisoActual][id] == FALSE) { printf("[ABRIR] O elevador nº %d abriu a porta\n", id+1);

Page 20: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

17

portaElevadores[pisoActual][id]= TRUE; } pthread_mutex_unlock(&muxPortaElevadores[pisoActual]); pthread_cond_broadcast(&elev_cond); } void close_door(int id, int pisoActual) { pthread_mutex_lock(&muxPortaElevadores[pisoActual]); printf("[FECHAR] O elevador nº %d fechou a porta\n", id+1); portaElevadores[pisoActual][id]= FALSE; pthread_mutex_unlock(&muxPortaElevadores[pisoActual]); } /********************************************************************************************************************* PESSOA *********************************************************************************************************************/ //definição das funções //fim da definição //funçoes void press_button(int piso) { pthread_mutex_lock(&muxBotaoChamada[piso]); botaoChamada[piso]=TRUE; pthread_mutex_unlock(&muxBotaoChamada[piso]); } int wait(int id,int piso) { int i; //int tempoEspera; pthread_mutex_lock(&muxPortaElevadores[piso]); for (i=0;i<=num_elevators;i++) { if (portaElevadores[piso][i] == TRUE) { printf("[ABRIR] Porta aberta do elevador %d no piso %d\n",i+1,piso); pthread_mutex_unlock(&muxPortaElevadores[piso]); return i; } } printf("\t[WAIT] Pessoa %d esperando...\n",id+1); while(1) { press_button(piso); pthread_cond_wait(&elev_cond,&muxPortaElevadores[piso]); for (i=0;i<=num_elevators;i++) { if (portaElevadores[piso][i] == TRUE) { printf("[ABRIR] Porta aberta do elevador %d no piso %d\n",i+1,piso); pthread_mutex_unlock(&muxPortaElevadores[piso]); return i; } } } } void get_in(int id,int elevador,int destino,int piso) { pthread_mutex_lock(&muxBotaoChamada[piso]); pthread_mutex_lock(&muxPisoAtendido[piso]); botaoChamada[piso]=FALSE; pisoAtendido[piso][0]=FALSE; pthread_mutex_unlock(&muxPisoAtendido[piso]); pthread_mutex_unlock(&muxBotaoChamada[piso]); pthread_mutex_lock(&muxPainelChamada[elevador]); painelChamada[elevador][destino] = TRUE; pthread_mutex_unlock(&muxPainelChamada[elevador]); printf("\t[ENTRAR] Pessoa %d entrou no elevador %d\n",id+1,elevador+1); } void go_on(int id,int elev,int destino) { pthread_mutex_lock(&muxPortaElevadores[destino]); while(1) { pthread_cond_wait(&elev_cond,&muxPortaElevadores[destino]); if (portaElevadores[destino][elev] == TRUE) { printf("[CHEGAR] Pessoa %d chegou ao piso %d\n",id+1,destino); pthread_mutex_unlock(&muxPortaElevadores[destino]); return; }

Page 21: Simulador de funcionamento de elevadores - …paginas.fe.up.pt/~ei02005/pagina/db/SO2.pdf · i Licenciatura em Engenharia Informática e Computação Simulador de funcionamento de

<Sistema de Funcionamento de Simulação de Elevadores>

18

} } void get_out(int id,int elevador,int destino) { pthread_mutex_lock(&muxPainelChamada[elevador]); painelChamada[elevador][destino] = FALSE; pthread_mutex_unlock(&muxPainelChamada[elevador]); printf("[CHEGAR] Pessoa %d saiu do elevador %d no piso %d\n",id+1,elevador+1,destino); } void *thr_pessoa(void *arg) { Pessoa pess; Estatistica stats; int id; int piso; void *stat; time_t firstArrival, firstDeparture,secondArrival, secondDeparture,firstStartJourney,firstFinishJourney,secondStartJourney,secondFinishJourney; id = (int) arg; pess.n_pess = id+1; pess.pisoDestino = rand()%(num_floors-1)+1; //Quer ir para o piso desejado time(&firstArrival); pess.elev= wait(id,0); time(&firstDeparture); //printf("fim do primeiro wait\n"); get_in(id,pess.elev,pess.pisoDestino,0); time(&firstStartJourney); go_on(id,pess.elev,pess.pisoDestino); time(&firstFinishJourney); get_out(id,pess.elev,pess.pisoDestino); printf("\t[WORKING] Pessoa %d está a trabalhar no piso %d\n",id+1,pess.pisoDestino); //Chegou a Piso Desejado sleep(workt); //Quer Sair do Edificio piso = pess.pisoDestino; pess.pisoDestino = 0; time(&secondArrival); pess.elev=wait(id,piso); time(&secondDeparture); get_in(id,pess.elev,0,piso); time(&secondStartJourney); go_on(id,pess.elev,0); time(&secondFinishJourney); get_out(id,pess.elev,0); int firstWait = (int)(firstDeparture-firstArrival); int secondWait = (int)(secondDeparture-secondArrival); int firstJourney = (int)(firstFinishJourney-firstStartJourney); int secondJourney = (int)(secondFinishJourney-secondStartJourney); stats.tempoMedioEspera = ((float)firstWait + (float)secondWait)/2; stats.tempoMedioViagem = ((float)firstJourney + (float)secondJourney)/2; if(firstWait >= secondWait) stats.tempoMaximoEspera = firstWait; else stats.tempoMaximoEspera = secondWait; if(firstJourney >= secondJourney) stats.tempoMaximoViagem = firstJourney; else stats.tempoMaximoViagem = secondJourney; stat = malloc(sizeof(Estatistica)); *(Estatistica *) stat = stats; return stat; }