假设您参加了公共灾难共和国的政党 一个带有n个盒子的浴室,盒子是带厕所的隔间。的规则 共和国说卫生间既可供男女使用,也可供同时使用。制作一个基于监视器的并发算法来控制此WC的使用。
进入浴室是通过浴室的程序进行的。成功进入浴室后,人们应该调用procedureBoxBox,使用一个盒子如果所有的盒子都在使用,那么他们应该排队等候,浴室里有足够的空间。使用盒子后,每个人都会调用该程序 liberaBox以便其他人可以使用它。
共和国仍然强制要求使用卫生间如下。假设浴室在某一点上被使用 同性(一些使用盒子和其他人等待),并且第一个异性的人到达,称为P. 所以:
•P从卫生间退出所有x个人后才进入浴室;
•只要P期待,如果其他同性人士到达,他们将同时使用卫生间P;
•当P在等待时,如果异性的人来洗手间,他们会在P(以及他们的同性伴侣,如果有的话)离开浴室后进入浴室;
•虽然P(和同性伴侣)正在使用卫生间,但如果与P同性,他们会在开始使用卫生间之前预期所有P异性的人都会离开。
每个男女都应该是一个单独的过程。没有人控制进入浴室,但所有人都知道使用浴室的规则并遵守它们(没有人坚持使用!)。
应该解决三个问题:
问题1: 考虑到浴室只有一个盒子(n = 1)。 总共有50个人会使用带有随机数发生器的浴室设置性别(概率相等)。
使用随机数生成器,以便到达人员之间的时间 在1到7秒之间.~
每个人使用浴室只需5秒钟。 使用线程和监视器进行同步。您还可以使用共享内存。 在程序结束时运行一个包含以下内容的报告:
•每个性别的人数;
•每个性别使用浴室的平均等待时间;
•盒子占用率(使用时间/总时间)。
问题2: 现在考虑浴室有3个盒子(n = 3),总人数是150。
问题3: 现在考虑浴室有5个盒子(n = 5),总人数是250
import threading
import random
from time import sleep
# constants
MALE = 1
FEMALE = 0
print("\n***************************************************************\nBem vindo ao banheiro unisex da Rep. Calamidade Pública\n***************************************************************\n\nDigite 1 para Problema 1\nDigite 2 para Problema 2\nDigite 3 para Problema 3\n\n***************************************************************")
print("")
menu = input("Seleção: ")
# global variables
queue = list() # to maintain queue outside bathroom
countPerson = 1 # provides id for each person
countMale = 0
countFemale = 0
PeopleInBathroom = 0
GenderUsingBathroom = 0
if menu == '1':
numBox = 1
elif menu == '2':
numBox = 3
elif menu == '3':
numBox = 5
# semaphores
sem_bathroom = threading.Semaphore(value=numBox)
sem_queue = threading.Semaphore()
sem_mutex = threading.Semaphore()
#generates people who need to use bathroom at random times
def GeneratePeople():
global queue
global countMale
global countFemale
global countPerson
if menu == '1':
sem_queue.acquire()
for i in range(0, 50):
if random.randint(0,1) == MALE:
queue.insert(0,[MALE,countPerson]);
countPerson += 1
countMale += 1
print ("Um homem chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
else:
queue.insert(0,[FEMALE,countPerson]);
countPerson += 1
countFemale += 1
print ("Uma mulher chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
sem_queue.release()
elif menu == '2':
sem_queue.acquire()
for i in range(0, 150):
if random.randint(0,1) == MALE:
queue.insert(0,[MALE,countPerson]);
countPerson += 1
countMale += 1
print ("Um homem chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
else:
queue.insert(0,[FEMALE,countPerson]);
countPerson += 1
countFemale += 1
print ("Uma mulher chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
sem_queue.release()
elif menu == '3':
sem_queue.acquire()
for i in range(0, 250):
if random.randint(0,1) == MALE:
queue.insert(0,[MALE,countPerson]);
countPerson += 1
countMale += 1
print ("Um homem chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
else:
queue.insert(0,[FEMALE,countPerson]);
countPerson += 1
countFemale += 1
print ("Uma mulher chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
sem_queue.release()
# end of GeneratePeople
# function to send people into bathroom for queue
def entraBanheiro():
global queue
global GenderUsingBathroom
global PeopleInBathroom
while 1:
sem_queue.acquire()
if len(queue)>0:
p = queue.pop()
sem_queue.release()
sem_mutex.acquire() # for GenderUsingBathroom
if GenderUsingBathroom == p[0] : # if same gender, go in
sem_mutex.release()
sem_bathroom.acquire()
t = threading.Thread(target=liberaBox,args=(p,))
t.start()
else: # if different gender, wait till all others come out
print ("Esperando por outra pessoa do mesmo sexo")
while PeopleInBathroom > 0:
sem_mutex.release()
sleep(1)
sem_mutex.acquire()
sem_mutex.release()
sem_bathroom.acquire()
GenderUsingBathroom = p[0]
t1 = threading.Thread(target=liberaBox,args=(p,))
t1.start()
else:
sem_queue.release()
# end of entraBanheiro
def liberaBox(person): # monitors the usage of bathroom for each person
global PeopleInBathroom
flag = 1
sem_mutex.acquire()
if person[0] == FEMALE:
print("Uma mulher acabou de entrar no banheiro")
flag = 0
else:
print ("Um homem acabou de entrar no banheiro")
PeopleInBathroom += 1 # enters bathroom
sem_mutex.release()
sleep(5) # spend some time in bathroom
sem_mutex.acquire()
PeopleInBathroom -= 1 #leave bathroom
print ("Pessoa #" , person[1]," acabou de sair do banheiro")
sem_mutex.release()
sem_bathroom.release()
# end of liberaBox
if __name__ == "__main__":
t1 = threading.Thread(target=GeneratePeople)
t1.start()
t2 = threading.Thread(target=entraBanheiro)
t2.start()
#print("\n***************************************************************\nEstatisticas\n\n***************************************************************\n")
#print("Homens: ", countMale)
#print("Mulheres: ", countFemale)
问题是代码首先生成所有人然后他们进入WC。如何同时为两个线程运行实现这个?
答案 0 :(得分:0)
def GeneratePeople():
global queue
global countMale
global countFemale
global countPerson
if menu == '1':
sem_queue.acquire()
for i in range(0, 50):
if random.randint(0,1) == MALE:
queue.put([MALE,countPerson]);
countPerson += 1
countMale += 1
print ("Um homem chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
else:
queue.put([FEMALE,countPerson]);
countPerson += 1
countFemale += 1
print ("Uma mulher chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
sem_queue.release()
elif menu == '2':
sem_queue.acquire()
for i in range(0, 150):
if random.randint(0,1) == MALE:
queue.put([MALE,countPerson]);
countPerson += 1
countMale += 1
print ("Um homem chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
else:
queue.put([FEMALE,countPerson]);
countPerson += 1
countFemale += 1
print ("Uma mulher chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
sem_queue.release()
elif menu == '3':
sem_queue.acquire()
for i in range(0, 250):
if random.randint(0,1) == MALE:
queue.put([MALE,countPerson]);
countPerson += 1
countMale += 1
print ("Um homem chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
else:
queue.put([FEMALE,countPerson]);
countPerson += 1
countFemale += 1
print ("Uma mulher chegou na fila na posição #", countPerson-1)
sleep(random.randint(1, 7))
sem_queue.release()
# end of GeneratePeople
# function to send people into bathroom for queue
def entraBanheiro():
global queue
global GenderUsingBathroom
global PeopleInBathroom
while 1:
sem_queue.acquire()
if queue.qsize() > 0:
p = queue.get()
sem_queue.release()
sem_mutex.acquire() # for GenderUsingBathroom
if GenderUsingBathroom == p[0] : # if same gender, go in
sem_mutex.release()
sem_bathroom.acquire()
t1 = threading.Thread(target=liberaBox,args=(p,))
t1.start()
else: # if different gender, wait till all others come out
print ("Esperando por outra pessoa do mesmo sexo")
while PeopleInBathroom > 0:
sem_mutex.release()
#sleep(1)
sem_mutex.acquire()
sem_mutex.release()
sem_bathroom.acquire()
GenderUsingBathroom = p[0]
t2 = threading.Thread(target=liberaBox,args=(p,))
t2.start()
else:
sem_queue.release()
# end of entraBanheiro
def liberaBox(person): # monitors the usage of bathroom for each person
global PeopleInBathroom
flag = 1
sem_mutex.acquire()
if person[0] == FEMALE:
print("Uma mulher acabou de entrar no banheiro")
flag = 0
else:
print ("Um homem acabou de entrar no banheiro")
PeopleInBathroom += 1 # enters bathroom
sem_mutex.release()
sleep(5) # spend some time in bathroom
sem_mutex.acquire()
PeopleInBathroom -= 1 #leave bathroom
print ("Pessoa #" , person[1]," acabou de sair do banheiro")
sem_mutex.release()
sem_bathroom.release()
# end of liberaBox
if __name__ == "__main__":
t3 = Process(target=GeneratePeople).start()
t4 = Process(target=entraBanheiro).start()
但现在我的问题是如何实施“每个性别使用卫生间的平均等待时间”和“盒子占用率(使用时间/总时间)”?