-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproblem_2.c
144 lines (112 loc) · 6.81 KB
/
problem_2.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <stdio.h>
#include <pthread.h> // Biblioteca para suporte a threads em C.
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include <time.h> // Biblioteca para manipulação de tempo.
#include <Windows.h>
#define NUM_CARROS 100 // Define o número de carros na simulação.
#define MAX_TEMPO_CHEGADA 3 // Define o tempo máximo de chegada dos carros.
#define TEMPO_TRAVESSIA 5 // Define o tempo de travessia de um carro.
#define TEMPO_ESPACO 1 // Define o intervalo entre os carros.
#define MAX_CARROS_PONTE 5 // Define o número máximo de carros que podem estar na ponte ao mesmo tempo.
#define MAX_CARROS_MESMO_SENTIDO 5 // Define o número máximo de carros na ponte antes de trocar o sentido.
// Inicialização de mutex e variáveis de condição para controle de concorrência.
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond[2] = {PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER};
// Declaração de variáveis globais para controlar o estado da ponte e coletar estatísticas.
int carros_na_ponte = 0;
int direcao_na_ponte = -1; // -1: ninguém na ponte, 0: direção 0, 1: direção 1
int contador_carros_mesmo_sentido = 0; // Variável adicional para contar os carros antes de trocar o sentido.
int carros_por_direcao[2] = {0, 0};
int tempo_max_espera = 0;
int tempo_min_espera = INT_MAX;
double tempo_total_espera = 0;
int tempo_total_execucao;
int tempo_total_ocupado = 0;
int ponte_ocupada = -1;
// Função que será executada por cada thread (carro).
void *carro(void *arg) {
int id = *((int *)arg);
int minha_direcao = id % 2; // A direção é determinada pelo id do carro.
// O carro espera um tempo aleatório antes de tentar atravessar a ponte.
sleep(rand() % MAX_TEMPO_CHEGADA + 1);
pthread_mutex_lock(&mutex); // Adquire o lock antes de manipular os recursos compartilhados.
int inicio_espera = time(NULL); // Registra o tempo de início da espera.
// Espera até que a ponte esteja vazia, ou carros estejam indo na mesma direção e haja espaço suficiente na ponte, ou que 5 carros da direção oposta tenham passado.
while (direcao_na_ponte != -1 && (direcao_na_ponte != minha_direcao || carros_na_ponte == MAX_CARROS_PONTE || contador_carros_mesmo_sentido == MAX_CARROS_MESMO_SENTIDO)) {
pthread_cond_wait(&cond[minha_direcao], &mutex); // Aguarda a notificação junto com os carros da mesma direção.
}
int fim_espera = time(NULL); // Registra o tempo de fim da espera.
int tempo_espera = fim_espera - inicio_espera; // Calcula o tempo total de espera.
// Atualiza as estatísticas de tempo de espera.
tempo_min_espera = tempo_espera < tempo_min_espera ? tempo_espera : tempo_min_espera;
tempo_max_espera = tempo_espera > tempo_max_espera ? tempo_espera : tempo_max_espera;
tempo_total_espera += tempo_espera;
//Se 5 carros já passaram e a ponte estiver vazia, define a direção do tráfego.
if (direcao_na_ponte == -1 || contador_carros_mesmo_sentido == MAX_CARROS_MESMO_SENTIDO) {
direcao_na_ponte = minha_direcao;
contador_carros_mesmo_sentido = 0;
if (ponte_ocupada == -1) {
ponte_ocupada = time(NULL); // Registra o tempo em que a ponte começou a ser ocupada.
}
}
// Atualiza o estado da ponte.
carros_na_ponte++;
contador_carros_mesmo_sentido++; // Incrementa o contador de carros no mesmo sentido.
carros_por_direcao[minha_direcao]++;
printf("Carro %d está atravessando na direção %d\n", id, minha_direcao); // Imprime que o carro começou a atravessar a ponte.
sleep(TEMPO_ESPACO); // Espera um intervalo antes de permitir o próximo carro.
pthread_mutex_unlock(&mutex); // Libera o lock após manipular os recursos compartilhados.
// Simula o tempo que o carro leva para atravessar a ponte.
sleep(TEMPO_TRAVESSIA);
pthread_mutex_lock(&mutex); // Adquire o lock novamente para atualizar o estado da ponte.
// Imprime que o carro terminou de atravessar a ponte.
printf("Carro %d terminou de atravessar na direção %d\n", id, minha_direcao);
carros_na_ponte--; // Decrementa o número de carros na ponte.
// Se a ponte estiver vazia, notifica carros da direção oposta. Caso contrário, notifica carros da mesma direção.
if (carros_na_ponte == 0) {
direcao_na_ponte = -1;
tempo_total_ocupado += time(NULL) - ponte_ocupada; // Atualiza o tempo total que a ponte foi ocupada.
ponte_ocupada = -1;
pthread_cond_broadcast(&cond[!minha_direcao]);
} else {
pthread_cond_signal(&cond[minha_direcao]);
}
// Libera o lock.
pthread_mutex_unlock(&mutex);
free(arg); // Libera a memória alocada para o id do carro.
return NULL;
}
// Função principal que inicializa e gerencia a simulação.
int main() {
SetConsoleOutputCP(CP_UTF8); // Define o conjunto de caracteres de saída do console para UTF-8.
pthread_t threads[NUM_CARROS]; // Declara um array de threads para cada carro.
int inicio_execucao = time(NULL); // Registra o tempo de início da execução.
// Cria as threads de carros.
for (int i = 0; i < NUM_CARROS; i++) {
int *id = malloc(sizeof(int)); // Aloca memória para o id do carro.
*id = i;
pthread_create(&threads[i], NULL, carro, id); // Cria a thread.
}
// Espera todas as threads de carros terminarem.
for (int i = 0; i < NUM_CARROS; i++) {
pthread_join(threads[i], NULL);
}
int fim_execucao = time(NULL); // Registra o tempo de fim da execução.
// Calcula o tempo total de execução.
tempo_total_execucao = fim_execucao - inicio_execucao;
// Imprime as estatísticas coletadas.
printf("\n-------------------------------------------------------------");
printf("\n| Estatísticas |\n");
printf("| |");
printf("\n| 🚗 Quantidade de Carros que cruzaram cada sentido: %d, %d |\n", carros_por_direcao[0], carros_por_direcao[1]);
printf("| 🚗 Tempo mínimo de espera para Carros: %d s |\n", tempo_min_espera);
printf("| 🚗 Tempo máximo de espera para Carros: %d s |\n", tempo_max_espera);
printf("| 🚗 Tempo médio de espera para Carros: %0.2f s |\n", tempo_total_espera / NUM_CARROS);
printf("| |");
printf("\n| ⏰ Eficiência da ponte: %0.2f%% |\n", ((double)tempo_total_ocupado / tempo_total_execucao) * 100);
printf("| |\n");
printf("-------------------------------------------------------------\n");
return 0;
}