-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
182 lines (153 loc) · 6.96 KB
/
main.py
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/env python
# coding: utf-8
"""
Controle de tráfego aéreo
Projeto da disciplina de Programação Paralela e Concorrente da Universidade Estadual do Ceará (UECE)
Semestre 2016.2
http://marcial.larces.uece.br/cursos/programacao-concorrente-e-paralela-2016-2/problema-controle-de-trafego-aereo
Desenvolvido por: Anderson Bezerra Ribeiro
Data: 08/06/2017
"""
import threading
from decorators.sync import synchronized
from classes.myThread import MyThread
from classes.track import Track
from random import choice
from time import time, sleep
class Aircraft:
def __init__(self, _id, _time_created, _local):
self.id = _id
self.time_created = _time_created
self.local = _local
self.final_time = 0.0
def __str__(self):
'''Sobrecarrega print para imprimir os dados do avião'''
return "<Avião {}> criado no {} aos {:.4f} segundos e removido aos {:.4f}. Tempo total: {:.4f}" \
.format(self.id,
self.local,
self.time_created,
self.final_time,
(self.final_time - self.time_created))
def status(self, type):
'''Imprime status da fila'''
if type == "gerar":
print("{:.4f}s - <Avião {}> gerado no {} - Fila Ar/Aeroporto [{}]/[{}] - Total Ar/Aeroporto: {}/{}"
.format(time() - initial_time,
self.id,
self.local,
len(pista.lista_ar),
len(pista.lista_aeroporto),
pista.avioes_do_ar,
pista.avioes_do_aeroporto))
elif type == "remover":
print("{:.4f}s - <Avião {}> removido do {} - Fila Ar/Aeroporto [{}]/[{}] - Total Ar/Aeroporto: {}/{}"
.format(time() - initial_time,
self.id,
self.local,
len(pista.lista_ar),
len(pista.lista_aeroporto),
pista.avioes_do_ar,
pista.avioes_do_aeroporto))
@synchronized
def verifica_proximo(self):
'''Verifica se o avião é o próximo a usar a pista. Se não for, entra em espera'''
if pista.mutex_pista._value > 0:
# Verifica previamente o valor do mutex para evitar aleatoriedade na escolha
if pista.lista_ar and pista.lista_ar[-1] == self: # Verifica se é a sua vez
tempo = time() - initial_time - self.time_created
if tempo > 20:
# Se avião tiver sido criado a mais de 20 segundos
pista.turn.clear()
self.pouso()
return
elif len(pista.lista_ar) > len(pista.lista_aeroporto):
# Se o número de aviões no ar for maior ou igual aos do aeroporto
pista.turn.clear()
self.pouso()
return
elif pista.lista_aeroporto and pista.lista_aeroporto[-1] == self:
if len(pista.lista_ar) <= len(pista.lista_aeroporto):
if not pista.lista_ar:
# Se não houver aviões no ar
pista.turn.clear()
self.voo()
return
elif pista.lista_ar and (time() - initial_time - pista.lista_ar[-1].time_created) < 20:
# Se houver mais aviões no aeroporto e nenhum criado a no mínimo 20 segundos no ar
pista.turn.clear()
self.voo()
return
def pouso(self):
'''Bloqueia a pista, realiza o pouso e libera a pista'''
print("-" * 50 + "\n{:.4f}s - <AVIÃO {}> OCUPANDO A PISTA PARA POUSO\n".format(time() - initial_time, self.id) + "-" * 50)
pista.adquire_pista()
pista.mutex_ar.acquire()
self.final_time = (time() - initial_time)
pista.lista_ar.pop()
self.status("remover")
pista.mutex_ar.release()
sleep(10)
pista.libera_pista()
file.write('-' + self.__str__() + '\n')
print("-" * 50 + "\n{:.4f}s - <AVIÃO {}> LIBEROU A PISTA\n".format(time() - initial_time, self.id) + "-" * 50)
pista.turn.set()
def voo(self):
'''Bloqueia a pista, realiza o voo e libera a pista'''
print("-" * 50 + "\n{:.4f}s - <AVIÃO {}> OCUPANDO A PISTA PARA VOO\n".format(time() - initial_time, self.id) + "-" * 50)
pista.adquire_pista()
pista.mutex_aeroporto.acquire()
self.final_time = (time() - initial_time)
pista.lista_aeroporto.pop()
self.status("remover")
pista.mutex_aeroporto.release()
sleep(10)
pista.libera_pista()
file.write('-' + self.__str__() + '\n')
print("-" * 50 + "\n{:.4f}s - <AVIÃO {}> LIBEROU A PISTA\n".format(time() - initial_time, self.id) + "-" * 50)
pista.turn.set()
def geradora():
'''Função base da thread de geração de aviões'''
i = 1
while pista.avioes_do_aeroporto < 10 or pista.avioes_do_ar < 10:
if pista.avioes_do_aeroporto < 10 and pista.avioes_do_ar < 10:
local_do_aviao = choice(["Aeroporto", "Ar"])
elif pista.avioes_do_aeroporto == 10:
local_do_aviao = "Ar"
else:
local_do_aviao = "Aeroporto"
if (local_do_aviao == "Aeroporto" and len(pista.lista_aeroporto) < pista.limite_lista) \
or (local_do_aviao == "Ar"):
aviao = Aircraft(i, (time() - initial_time), local_do_aviao)
pista.adiciona_na_lista(aviao)
nova_thread = MyThread(t_avioes, (aviao,))
nova_thread.start()
i += 1
else:
file.write("--ERRO-- Fila cheia")
print("--ERRO-- Fila cheia")
sleep(8)
def t_avioes(t_aviao):
'''Função base da thread do avião que o coloca em loop até que seja sua vez'''
if t_aviao.local == "Aeroporto":
while t_aviao in pista.lista_aeroporto:
if not pista.turn.is_set():
pista.turn.wait()
t_aviao.verifica_proximo()
else:
while t_aviao in pista.lista_ar:
if not pista.turn.is_set():
pista.turn.wait()
t_aviao.verifica_proximo()
initial_time = time() # Momento em que o programa iniciou
pista = Track() # Cria pista
pista.turn.set()
file = open("LOG.txt", 'w') # Cria arquivo de log
file.write("---------- LOG DE EXECUÇÃO ----------\n\n")
thread_geradora = MyThread(geradora, ()) # Instancia thread geradora
thread_geradora.start() # Inicia thread geradora
while pista.avioes_do_ar < 10 or pista.avioes_do_aeroporto < 10 or len(pista.lista_ar) > 0 or len(pista.lista_aeroporto) > 0:
pass
sleep(10)
print("\n{:.4f}: Fim da execução\n".format(time() - initial_time))
print("Nenhum avião foi derrubado durante o desenvolvimento desse programa") # Mensagem importante
file.close() # Fecha arquivo de log