2017-03-01 20 views
0

私はこれをたくさん見つけて答えを得ませんでした。タスクを待っている並行スレッド

今日は一日でしたが、私のコードが混乱している理由のいくつかのスレッディング概念を得ることはできません。

私は3つのスレッドを生成しています。ファイン。

スレッド2が発生すると、スレッド1は「停止する」と判断して終了することを意味します。スレッド2と3で同じです。

私はこれらのスレッドをアクティブなプールに入れています。

私が苦労しているのは、3つのスレッドを同時に実行して待機させることです。私はランダムな時間間隔でタスクにスレッドを割り当てるメソッドを持っていたいと思います。

私が集めたことから、私のスレッドが死んでいる理由は、私のワーカークラスが復帰しているからです。しかし、それを演奏してループの周りに置いて(1つの間)、私はまだ何かを得ることができません。

アイデア?

import logging 
import random 
import threading 
import time 

logging.basicConfig(level = logging.DEBUG, format = '(%(threadName)-2s) %(message)s') 

class ActivePool(object): 
    def __init__(self): 
     super(ActivePool, self).__init__() 

     self.active = [] 
     self.lock = threading.Lock() 

    def activate(self, name): 
     with self.lock: 
      self.active.append(name) 
      logging.debug('Running wheel: %s', self.active) 
      self.move(name) 

    def move(self, name): 
     while name.is_alive(): 
      logging.debug('yes') 

    def inactive(self, name): 
     with self.lock: 
      self.active.remove(name) 
      logging.debug('Running wheel: %s', self.active) 

    def rtime(self): 
     self.rt = random.randint(5, 10) 
     t = threading.Timer(rt, self.revent) 

    def join(self): 
     for t in self.active: 
      t.join() 

    def check(self): 
     for t in self.active: 
      if t.is_alive(): 
       print t 

def worker(s, pool): 
    logging.debug('Wheel inactive') 

    with s: 
     #name = threading.currentThread().getName() 
     thread = threading.currentThread() 
     logging.debug('ACTIVATING') 
     pool.activate(thread) 
     #time.sleep(2) 
     #pool.inactive(thread) 

if __name__ == "__main__": 
    pool = ActivePool() 
    s = threading.Semaphore() 

    for i in range(0, 6): 
     t = threading.Thread(target = worker, name = str(i + 1), args = (s, pool)) 
     pool.activate(t) 
     t.start() 

    logging.debug('here') 
+0

ここでも擬似コードを追加すると役立ちます。そうでなければ診断す​​るのはかなり難しいでしょう。 –

+0

@phyllisdillerが追加されました – popopret

+0

少し物事をきれいにすると、スレッド1が回転して死ぬことはありません。 しかし、私はその意図がわからない。あなたは本質的にタスクを割り当てられるのを待っているスレッドのプールを持っていますが、正しいですか? しかし、主関数とワーカー関数(スレッドが実行するもの)は、スレッドをアクティブにします。スレッド内からスレッドをアクティブにするべきではありません。 –

答えて

0

いいえ。私は少し物事をrejiggeredしました。本質的にあなたが望むのは、このコマンドの順序です:

  • ActivePoolを構築します。
  • ActivePoolにスレッドを追加します。
  • ActivePool.start()を呼び出してスレッドを開始します。
  • ワーカースレッドは、セマフォによって保護された共有データを使用してワーカー関数を実行します。
  • メインスレッドはすべてのスレッドの完了を待ちます。

スレッドに参加する必要はありません。

ランダムタスクを追加する場合は、ワーカー関数が引き出して作業を実行するいくつかのリスト(セマフォでロックする必要があります)に追加します。作業者がリスト内の何かを見ると、それはリストから取り除かれ、関連するアクションを実行します。何もする必要がなければ、スレッドをスリープ状態にしてください。

スレッドプールにスピンアップする前に、すべてのスレッドをスレッドプールに追加することができます(つまり、ActivePool内でリストを作成し、pool.activate()を実行して各スレッドを順番にアクティブにすることができます)。

import logging 
import random 
import threading 
import time 

logger = logging.getLogger("thread_logger") 
logger.setLevel(logging.DEBUG) 

class ActivePool(object): 
    def __init__(self): 
     super(ActivePool, self).__init__() 

     self.active = [] 
     self.lock = threading.Lock() 

    def activate(self, name): 
     with self.lock: 
      self.active.append(name) 
      logger.debug('Running wheel: %s', self.active) 
      t.start() 

    def inactive(self, name): 
     with self.lock: 
      self.active.remove(name) 
      logger.debug('Running wheel: %s', self.active) 

    def rtime(self): 
     self.rt = random.randint(5, 10) 
     t = threading.Timer(rt, self.revent) 

    def join(self): 
     for t in self.active: 
      t.join() 

    def check(self): 
     for t in self.active: 
      if t.is_alive(): 
       return True 

def worker(s, pool): 

    logger.debug('Worker spinning up') 

    for x in range(0, 3): 
     with s: 
      logger.debug('Thread ID: ' + str(threading.currentThread().ident) + ' DO WORK: ' + str(x)) 
     time.sleep(2) 

if __name__ == "__main__": 

    pool = ActivePool() 
    s = threading.Semaphore() 

    for i in range(0, 2): 
     t = threading.Thread(target = worker, name = str(i + 1), args = (s, pool)) 
     pool.activate(t) 

    while(pool.check()): 
     print("Worker thread still workin yo.") 
     time.sleep(2) 
    logger.debug('Finito.') 
関連する問題