2012-11-30 13 views
5

Używam przetwarzania wieloprocesowego w moim projekcie. Mam funkcję pracownika, która umieszcza w kolejce wyniki. Wszystko dziala. Ale ponieważ rozmiar x rośnie (w moim przypadku x to tablica) coś poszło nie tak. Tutaj jest uproszczoną wersją mojego kodu:Wielokrotne przetwarzanie w python zablokowany

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 

widzę w systemie monitorowania procesów python działa, ale potem coś się stało i wszystkie procesy są uruchomione, ale nic nie robi. To właśnie dostaję podczas wpisywania ctrl-D.

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

Wykonuję niektóre testy. Problem polega na tym, że umieszczanie wyników w kolejce jest faktem, jeśli nie umieszczę wyników, wszystko działa, ale wtedy nie byłoby żadnego celu.

+4

Wydaje się, że nigdy nie przekazujesz obiektu kolejki do nowego procesu. Również 'args' z' Process' powinno być 'krotką'. Spróbuj zmienić go na 'args = (queue, i)'. Twój 'queue.get' również wymaga pewnych nawiasów, aby stał się' queue.get() '. – Wessie

Odpowiedz

3

Wygląda na to, że jest to błąd w module kolejki pythona. W rzeczywistości za pomocą ..

from multiprocessing import Manager 

queue = Manager().Queue() 

..everything działa, ale ja nadal nie wiem dlaczego .. :)

+0

Różnica polega na tym, że tworzysz 'Manager(). Queue()' zamiast po prostu 'Queue()'. Myślę, że oznacza to, że 'Manager .__ init __()' zostaje wywołany w pierwszej formie, ale nie w drugiej. – Patrick

5

Jesteś najprawdopodobniej generowania impasu.

Z programming guidelines:

Oznacza to, że przy każdym użyciu kolejkę trzeba upewnić się, że wszystkie elementy, które zostały umieszczone w kolejce zostaną ostatecznie usunięte zanim proces jest połączone. W przeciwnym razie nie można mieć pewności, że procesy, które umieściły elementy w kolejce, zostaną zakończone. Pamiętaj także, że procesy nie-demoniczne zostaną automatycznie połączone.

Możliwe poprawki są również proponowane na stronie. Należy pamiętać, że jeśli procesy nie są połączone, nie oznacza to, że w jakimś sensie "okupują" zasoby. Oznacza to, że można uzyskać dane w kolejce po zakończeniu procesów (być może przy użyciu locks) i dopiero później dołączyć do procesów.