Created
April 27, 2018 02:18
-
-
Save matbrgz/04540370dcf2381b25872694c1914b71 to your computer and use it in GitHub Desktop.
Problema do Banheiro Unissex - 3 Cenários utilizando semáforos
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from multiprocessing import Process, Queue | |
import threading | |
import random | |
import time | |
from time import sleep | |
import os | |
# constantes | |
MALE = 1 | |
FEMALE = 0 | |
# menu | |
print("{0}\nBem vindo ao banheiro unisex da Rep. Calamidade Pública\n{0} \ | |
\n\nDigite 1 para Problema 1\nDigite 2 para Problema 2\nDigite 3 para Problema 3\n\n{0}".format(60 * "*")) | |
menu = input("Seleção: ") | |
print("{0}".format(60 * "*")) | |
# váriaveis globais | |
queue = Queue() # para manter a fila fora do banheiro | |
countPerson = 1 # fornece id para cada pessoa | |
countMale = 0 # contador de homens | |
countFemale = 0 # contador de mulheres | |
countBathroom = 0 # contador de pessoas dentro do banheiro | |
# flag para verificar qual sexo esta dentro do banheiro | |
genderBathroom = 0 | |
startMaleTime = [] # | |
startFemaleTime = [] # | |
endMaleTime = [] # | |
endFemaleTime = [] # | |
meanMale = 0 # | |
meanFemale = 0 # | |
endTime = 0 # | |
totalTime = 0 # | |
startBoxTime = [] # | |
endBoxTime = [] # | |
totalBoxTime = 0 # | |
startTime = time.time() # | |
# número de boxes de acordo com cenario | |
if menu == '1': # cenário 1 - 1 box | |
numBox = 1 | |
numPeople = 50 | |
elif menu == '2': # cenário 2 - 3 boxes | |
numBox = 3 | |
numPeople = 150 | |
else: # cenário 3 - 5 boxes | |
numBox = 5 | |
numPeople = 250 | |
# semáforos | |
sem_bathroom = threading.Semaphore(value=numBox) | |
sem_queue = threading.Semaphore() | |
sem_mutex = threading.Semaphore() | |
def entraFila(): # gera pessoas que precisam usar o banheiro em tempos aleatórios | |
global queue | |
global countPerson | |
global startMaleTime | |
global startFemaleTime | |
sem_queue.acquire() | |
for i in range(0, numPeople): # cenário 1 - 50 pessoas | |
if random.randint(0, 1) == MALE: # verifica se é homem | |
startMaleTime.append(time.time()) | |
queue.put([MALE, countPerson]) | |
countPerson += 1 | |
print ("QUEUE> Pessoa #", countPerson, | |
" : Um HOMEM chegou na fila") | |
sleep(random.randint(1, 7)) | |
else: | |
startFemaleTime.append(time.time()) | |
queue.put([FEMALE, countPerson, ]) | |
countPerson += 1 | |
print ("QUEUE> Pessoa #", countPerson, | |
" : Uma MULHER chegou na fila") | |
sleep(random.randint(1, 7)) | |
sem_queue.release() | |
def entraBanheiro(): # função para enviar pessoas para o banheiro para fila | |
global queue | |
global genderBathroom | |
global countBathroom | |
while 1: | |
sem_queue.acquire() | |
if queue.qsize() > 0: | |
p = queue.get() | |
sem_queue.release() | |
sem_mutex.acquire() # para genderBathroom | |
if genderBathroom == p[0]: # se o mesmo gênero, entre | |
sem_mutex.release() | |
sem_bathroom.acquire() | |
t1 = threading.Thread(target=liberaBox, args=(p,)) | |
t1.start() | |
else: # se diferente gênero, espere até que todos os outros saem | |
print("WAIT> Esperando por outra pessoa do mesmo sexo") | |
while countBathroom > 0: | |
sem_mutex.release() | |
sem_mutex.acquire() | |
sem_mutex.release() | |
sem_bathroom.acquire() | |
genderBathroom = p[0] | |
t2 = threading.Thread(target=liberaBox, args=(p,)) | |
t2.start() | |
else: | |
sem_queue.release() | |
def liberaBox(person): # monitora o uso de banheiro para cada pessoa | |
global countMale | |
global countFemale | |
global countBathroom | |
global endMaleTime | |
global endFemaleTime | |
global startBoxTime | |
global endBoxTime | |
flag = 1 | |
sem_mutex.acquire() | |
if person[0] == FEMALE: | |
countFemale += 1 | |
endFemaleTime.append(time.time()) | |
print("JOIN> Pessoa #", person[len(person) - 1], | |
": Uma MULHER acabou de entrar no banheiro") | |
flag = 0 | |
else: | |
countMale += 1 | |
endMaleTime.append(time.time()) | |
print ("JOIN> Pessoa #", person[len( | |
person) - 1], ": Um HOMEM acabou de entrar no banheiro") | |
countBathroom += 1 # entra no banheiro | |
startBoxTime.append(time.time()) | |
sem_mutex.release() | |
sleep(1) # passar algum tempo no banheiro | |
sem_mutex.acquire() | |
endBoxTime.append(time.time()) | |
countBathroom -= 1 # sai do banheiro | |
print ("EXIT> Pessoa #", person[len( | |
person) - 1], ": Acabou de sair do banheiro") | |
if person[len(person) - 1] == numPeople: | |
endTime = time.time() | |
print("\n{0}\nEstatisticas\n{0}\n".format(60 * "*")) | |
print("Total de pessoas:", countMale + countFemale) | |
print("Total de Homens: ", countMale) | |
print("Total de Mulheres: ", countFemale) | |
print("\n{0}\n".format(60 * "*")) | |
meanMale = sum(endMaleTime) - sum(startMaleTime) | |
meanFemale = sum(endFemaleTime) - sum(startFemaleTime) | |
print("Tempo Médio de Espera HOMENS:", meanMale / countMale) | |
print("Tempo Médio de Espera MULHERES:", meanFemale / countFemale) | |
totalTime = endTime - startTime | |
totalBoxTime = sum(endBoxTime) - sum(startBoxTime) | |
print("Tempo de Execução:", totalTime) | |
print("Tempo em Uso:", totalBoxTime) | |
print("Taxa de Ocupação do Box:", totalBoxTime / totalTime) | |
print("\n{0}\n".format(60 * "*")) | |
sem_mutex.release() | |
sem_bathroom.release() | |
if __name__ == "__main__": | |
t3 = Process(target=entraFila) | |
t3.start() | |
t4 = Process(target=entraBanheiro) | |
t4.start() | |
t3.join() | |
t4.join() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment