2017-03-01 6 views
0

Ich habe dies jetzt viel gegoogelt und kam zu keiner Antwort - daher warum ich frage.Concurrent Threads warten auf Aufgaben

Schon ein Tag, aber ich kann einige Threading-Konzepte nicht umgehen, was wahrscheinlich ist, warum mein Code ein Durcheinander ist.

Ich spawne 3 Threads. Fein.

Wenn Thread 2 spawnt, Faden 1 "stoppt", was bedeutet, dass es stirbt. Dasselbe gilt für Thread 2 und 3.

Ich setze diese Threads in einen aktiven Pool.

Womit ich kämpfe, ist, alle 3 Fäden gleichzeitig laufen zu lassen und zu warten. Ich hätte gerne eine Methode, die in zufälligen Zeitintervallen einen Thread einer Aufgabe zuweist.

Von dem, was ich gesammelt habe, ist der Grund, warum meine Threads sterben, weil meine Arbeiterklasse zurückkehrt. Aber nachdem ich damit gespielt und es um eine Schleife gelegt habe (während 1), kann ich immer noch nichts arbeiten.

Irgendwelche Ideen?

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

Selbst das Hinzufügen eines Pseudocodes würde helfen. Es wird ziemlich schwer sein, das anders zu diagnostizieren. –

+0

@phyllisdiller hinzugefügt – popopret

+0

Wenn ich die Dinge ein bisschen aufräumen, bekomme ich Thread 1 dreht sich und nicht zu sterben. Aber ich bin mir der Absicht nicht sicher. Sie möchten im Wesentlichen einen Pool von Threads haben, die auf zugewiesene Aufgaben warten, richtig? Ihre Hauptfunktion, sowie Ihre Worker-Funktion (die Sache, die der Thread ausführen wird), aktiviert jedoch den Thread. Sie sollten den Thread nicht innerhalb des Threads aktivieren. –

Antwort

0

Okay. Ich habe die Dinge ein wenig rejiggeriert. Im Wesentlichen, was Sie wollen, ist diese Reihenfolge des Befehls:

  • Erstellen Sie einen ActivePool.
  • Hinzufügen von Threads zu Ihrem ActivePool.
  • Rufen Sie ActivePool.start() auf, um den Thread zu beginnen.
  • Die Worker-Threads führen die Worker-Funktion mit gemeinsamen Daten aus, die vom Semaphor geschützt werden.
  • Der Haupt-Thread wartet auf die Fertigstellung aller Threads.

Sie müssen die Threads nicht verbinden.

Wenn Sie eine zufällige Aufgabe hinzufügen, fügen Sie sie zu einer Liste hinzu (die Sie mit Ihrem Semaphor sperren müssten), von der die Worker-Funktion ausgeht und an der Sie arbeiten. Wenn der Mitarbeiter etwas in der Liste sieht, wird er von der Liste entfernt und die entsprechende Aktion ausgeführt. Wenn es nichts zu tun gibt, lass den Faden schlafen.

Sie möchten möglicherweise alle Ihre Threads zu Ihrem Thread-Pool hinzufügen, bevor Sie sie aufdrehen (d. H., Erstellen Sie eine Liste in ActivePool, dann tun pool.activate() und aktivieren Sie jeden Thread der Reihe nach).

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.') 
Verwandte Themen