2012-11-30 22 views
5

Ich verwende Multiprocessing in meinem Projekt. Ich habe eine Arbeiterfunktion, die die Ergebnisse in eine Warteschlange stellt. Alles funktioniert gut. Aber wenn die Größe von x zunimmt (in meinem Fall ist x ein Array), ist etwas falsch gelaufen. Hier ist eine vereinfachte Version von meinem Code:Multiprocessing in Python blockiert

def do_work(queue, x): 
    result = heavy_computation_function(x) 
    queue.put(result) # PROBLEM HERE 

def parallel_something(): 
    queue = Queue() 
    procs = [Process(target=do_work, args=i) for i in xrange(20)] 
    for p in procs: p.start() 
    for p in procs: p.join() 

    results = [] 
    while not queue.empty(): 
     results.append(queue.get) 

    return results 

ich im System sehen überwachen, die Python-Prozesse arbeiten, aber dann etwas passieren und alle Prozesse laufen aber nichts zu tun. Das ist, was ich bekomme, wenn ich ctrl-D eintippe.

pid, sts = os.waitpid(self.pid, flag) 
KeyboardInterrupt 

Ich mache ein paar Tests. Und das Problem sieht so aus, als würde man die Ergebnisse in die Warteschlange stellen, wenn ich die Ergebnisse nicht packe, funktioniert alles, aber dann wäre es sinnlos.

+4

Sie scheinen das Warteschlangenobjekt niemals an den neuen Prozess zu übergeben. Auch "Args" von "Process" sollte ein "Tupel" sein. Versuchen Sie es in 'args = (queue, i)' zu ändern. Ihr 'queue.get' benötigt ebenfalls einige Klammern, so dass es' queue.get() 'wird. – Wessie

Antwort

3

Nun, es sieht so aus, als wäre es ein Fehler im Queue-Modul von Python. In der Tat mit ..

from multiprocessing import Manager 

queue = Manager().Queue() 

Werke ..everything aber ich weiß noch nicht, warum .. :)

+0

Der Unterschied besteht darin, dass Sie 'Manager(). Queue()' statt einfach 'Queue()' instanziieren. Ich denke, das bedeutet, dass 'Manager .__ init __()' in der ersten Form aufgerufen wird, aber nicht in der zweiten. – Patrick

5

Sie sind höchstwahrscheinlich eine Sackgasse zu erzeugen.

Vom programming guidelines:

Das bedeutet, dass, wenn Sie eine Warteschlange verwenden Sie sicherstellen müssen, dass alle Elemente, die in die Warteschlange gestellt wurden, werden schließlich entfernt werden, bevor der Prozess verbunden ist. Andernfalls können Sie nicht sicher sein, dass Prozesse, die Elemente in die Warteschlange aufgenommen haben, beendet werden. Denken Sie auch daran, dass nicht-dämonische Prozesse automatisch verknüpft werden.

Eine mögliche Lösung wird ebenfalls auf der Seite vorgeschlagen. Denken Sie daran, dass, wenn Prozesse nicht verbunden werden, dies nicht bedeutet, dass sie Ressourcen in irgendeiner Weise "besetzen". Dies bedeutet, dass Sie die in die Warteschlange gestellten Daten nach Abschluss der Prozesse abrufen könnten (möglicherweise unter Verwendung von locks) und erst später an den Prozessen teilnehmen.