2017-12-05 12 views
0

パブリックカラミティ共和国のパーティーで、 トイレ付きのコンパートメントであるボックスがあるボックスが の場合のみを考えてみましょう。 共和国の規則では、トイレは男性と女性の両方で使用できるが、同じ時間に使用することはできないという。このWCの使用を制御する同時モニターベースのアルゴリズムを作成します。Pythonで分散と並列コンピュータのユニセックスバスルームソリューション

バスルームへの入室は、バスルーム内の手順で行います。バスルームに正常に入った後、ボックスを使用するには、procedureBoxBoxを呼び出す必要があります。すべてのボックスが使用されている場合、キュー内で待機する必要があります。ボックスを使用した後、各人が手順 liberaBoxを呼び出し、他の人が使用できるようにします。

共和国は依然として、浴室の使用が次のように公平でなければならないことを課しています。ある時点で、 同性愛者(同じものを使用しているものもあれば他人が待っている)によって使用されていると仮定した場合、P. と呼ばれる。

•Pは、すべてのx個の人がバスルームから退出する。

•Pが期待している限り、他の同性の人が到着した場合、Pと同時にトイレを使用します。

•Pが待っている間に、異性の人がバスルームを使用すると、Pの後にトイレに入る(そして同性の相手がいる場合)。

•P(と同性の仲間)は、Pと同じ性別であればトイレを使用していますが、トイレの使用を開始する前に、Pからの異性のすべての人々が離れることを期待します。

それぞれの男女は別々のプロセスである必要があります。バスルームへのアクセスを制御する人はいませんが、誰もがバスルームを使用するルールを知っており、それに従うことはできません。

三つの問題に対処する必要があります。

問題1: バスルームには、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) 

問題コードがそれらが入力し第一すべての人々を生成であることトイレ。どのように両方のスレッドの実行同時にこれを実装するには?

+1

スレッディングの代わりにマルチプロセッシングを使用します。 Pythonのスレッドは実際には並列ではありません。これを見てください:https://stackoverflow.com/questions/1697571/python-threading-appears-to-run-threads-sequentially これはあなたが探しているものです:https://stackoverflow.com/questions/ 2046603 /スレッドなしまたはサブスクリプションなしで実行可能なサブプロセスの機能 – epinal

+0

プロセスを実装する方法はありませんか? – MatheusVieira

+0

https://stackoverflow.com/a/2046630/4585081 キューをマルチプロセッシングキューに変更してください。 joinを呼び出す前に、2つのプロセスをスパムします。 – epinal

答えて

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() 

しかし、今、私の質問は、「各性のためにバスルームを使用するための平均待ち時間」と「ボックス占有率(使用中の時間/総時間)」を実装する方法ですか?

関連する問題