2016-10-07 8 views
-1

配列項目をPythonで順番に印刷するには、3つのスレッドを使用する必要があります。スレッドをPythonと同期して実行するには?

各スレッドは1つの配列項目を出力します。

スレッドを数秒間スリープさせてからアイテムを印刷する必要があります。

この機能はN回実行されます。このN値はユーザによって与えられる。

項目は特定の順序で印刷する必要があります。つまり、前の項目が実行されていない間に実行する他のスレッドを何らかの形でブロックする必要があります。 私はさまざまなソリューションを試してきましたが、それを動作させる方法を理解できません。

セマフォ、ロック、イベントを使用しようとしましたが、同期に成功しませんでした。すべての場合、それはシーケンス自体ではなく、time.sleepに従ってランダムにシーケンスを出力します。どのようにスレッドが関数を実行するのをブロックし、シーケンスが動作するために前のスレッドが終了したかどうかを確認できますか?

どのツールを使用して動作させる必要がありますか?どんな助けもありがとうございます。

class myThread(threading.Thread): 
def __init__(self, group=None, target=None, name=None, 
      args=(), kwargs=None, verbose=None): 
    super(myThread,self).__init__() 
    self.target = target 
    self.name = name 
    return 

def run(self): 
    while True: 
     if not q.empty(): 
      semaphore.acquire() 
      try: 
       time_sleep = random.randrange(0,10) 
       print "thread " + self.name + ". Dormir por " + str(time_sleep) + " segundos" 
       time.sleep(time_sleep) 
       print cores[int(self.name)] 
       if int(self.name) == len(cores) - 1: 
        item = q.get() 
        print 'Executou sequencia ' + str(item + 1) + ' vezes. Ainda irá executar ' + str(q.qsize()) + ' vezes' 
        e.set() 
      finally: 
       semaphore.release() 
       if int(self.name) != len(cores) - 1: 
        e.wait() 
    return 

if __name__ == '__main__': 
    for i in range(2): 
     q.put(i) 

    for i in range(3): 
     t = myThread(name=i) 
     t.start() 
+1

この動作が必要な場合は、なぜ最初にスレッドを使用していますか?また、「私はたくさんの努力をしています」と言って、あなたの試行錯誤とあなたの期待に応えられなかったことを示してください。 – That1Guy

答えて

1

これには多くのアプローチがあります。単純なものは、数字の共有Queueを使用することです。

各スレッドは長い間スリープすることができます。スリープ状態になるとキューから番号を取り出して印刷します。彼らはキューにプッシュされた順に出てくるでしょう。

数字が連続している場合や、動的に生成できる場合は、共有カウンタas described in this answerを使用して定数メモリで行うこともできます。

+0

スレッド1が8秒間スリープし、スレッド3が0秒間スリープした場合、スレッド3はスレッド1の前に印刷され、シーケンスに従わないため、問題は解決しません。私は今質問にも一片のコードを掲載しました...私は、クエリーを使用して、queシーケンスが呼び出された回数をチェックし、最後のスレッドである場合には1つのアイテムを取得しました。 –

+0

私が理解しているように、数字は順番に印刷されなければなりません。それじゃない? – slezica

0

注文を気にしなかった場合は、ロックを使用してアクセスを同期するだけで済みます。しかしこの場合、イベントのリストはどうですか?各スレッドは独自のイベントスロットを取得し、完了するとリストの次のイベントに渡します。このスキームは、明示的にリリースする必要がないようにコンテキストマネージャを返すことによって魅了される可能性があります。

import threading 

class EventSlots(object): 

    def __init__(self, num_slots): 
     self.num_slots = num_slots 
     self.events = [threading.Event() for _ in range(num_slots)] 
     self.events[0].set() 

    def wait_slot(self, slot_num): 
     self.events[slot_num].wait() 
     self.events[slot_num].clear() 

    def release_slot(self, slot_num): 
     self.events[(slot_num + 1) % self.num_slots].set() 


def worker(event_slots, slot_num): 
    for i in range(5): 
     event_slots.wait_slot(slot_num) 
     print('slot', slot_num, 'iteration', i) 
     event_slots.release_slot(slot_num) 


NUM = 3 

slots = EventSlots(NUM) 

threads = [] 

for slot in range(NUM): 
    t = threading.Thread(target=worker, args=(slots, slot)) 
    t.start() 
    threads.append(t) 

for t in threads: 
    t.join() 
+0

私は注文について気にします、それは今私のための主要な問題です。私は今まで自分のコードを投稿しています –

関連する問題