Skip to content

Instantly share code, notes, and snippets.

@matbrgz
Created April 27, 2018 02:18
Show Gist options
  • Save matbrgz/04540370dcf2381b25872694c1914b71 to your computer and use it in GitHub Desktop.
Save matbrgz/04540370dcf2381b25872694c1914b71 to your computer and use it in GitHub Desktop.
Problema do Banheiro Unissex - 3 Cenários utilizando semáforos
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