Python中的分布式并行计算机中性浴室解决方案

2024-04-19 08:27:56 发布

您现在位置:Python中文网/ 问答频道 /正文

假设你在公共灾难共和国的一个派对上 带n个盒子的浴室,盒子是带马桶的隔间。规则 共和国说,浴室可供男性和女性使用,但不能同时使用。制作一个基于并发监视器的算法来控制这个WC的使用。你知道吗

进入浴室是按照浴室的程序进行的。在成功进入浴室后,人们应该调用程序reboxbox,使用一个盒子如果所有的盒子都在使用,那么他们应该排队等候,浴室里有足够的空间。在使用一个框之后,每个人都调用这个过程 把盒子打开,让别人可以用。你知道吗

共和国仍然强制规定浴室的使用应该是公平的,如下所示。假设在某一点上,浴室被 同性(有的用盒子,有的等着),第一个异性来了,叫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。如何为同时运行的两个线程实现这一点?你知道吗


Tags: releaseifqueuesleeprandomglobalprintrandint
1条回答
网友
1楼 · 发布于 2024-04-19 08:27:56
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()

但现在我的问题是如何实现“每个性别使用浴室的平均等待时间”和“箱子占用率(使用时间/总时间)”?

相关问题 更多 >