2015-05-28 8 views
6

Wprowadzam bibliotekę wieloprocesorową Pythona przy użyciu puli pracowników. Zaimplementowałem następujący kod:Python Multiprocessing prowadzący do wielu procesów zombie

import main1 
t1 = time.time() 
p = Pool(cores) 
result = p.map(main1, client_list[client]) 
if result == []: 
    return [] 
p.close() 
p.join() 
print "Time taken in performing request:: ", time.time()-t1 
return shorted(result) 

Jednak po uruchomieniu procesu przez pewien czas otrzymuję wiele działających procesów w tle mojej aplikacji. Oto migawki po wykonaniu ps aux do mojego app

Snapshot showing all the zombie processes

Teraz, czytałem wiele podobnych pytań na StackOverflow jak how to kill zombie processes created by multiprocessing module? który wzywa do korzystania .join(), która już wdrożone i nauczyłem jak zabić wszystkie te procesy stąd Python Multiprocessing Kill Processes. Ale chcę wiedzieć, co może pójść nie tak z moim kodem. Nie będę w stanie udostępnić całego mojego kodu w funkcji main1, ale włożyłem cały blok kodu do bloku catch catch, aby uniknąć przypadków, w których błąd w głównym kodzie mógłby doprowadzić do procesów zombie.

def main1((param1, param2, param3)): 
    try: 
     resout.append(some_data) //resout in case of no error 
    except: 
     print traceback.format_exc() 
     resout = [] //sending empty resout in case of error 
    return resout 

nadal jestem bardzo nowym pojęciem zagadnień programowania i debugowania równolegle z nim obraca się tricky.Any pomoc będzie bardzo mile widziane.

+0

Niestety, napisany przez Ciebie kod nie pomaga w zdiagnozowaniu problemu. Zbyt wiele niewyjaśnionych zmiennych i, co ważniejsze, nie jest jasne z tego, co napisałeś, jak kod jest wywoływany, i co się dzieje po powrocie twojej funkcji. Moje pierwsze wrażenie jest takie, że tworzysz wiele pul w pętli, zamiast wielokrotnie używać pulę. Ale nie mogę być tego pewien. – justinpawela

+0

[Powinieneś tak skonstruować swój kod.] (Http://pymotw.com/2/multiprocessing/communication.html#process-pools) Jeśli masz dużo pracy do wykonania, powinieneś używać tej samej puli w kółko (możesz tylko nazwać 'Pool()' raz). Kiedy już skończysz z procesami roboczymi, ważne jest wywoływanie 'close' i' join '- to one sygnalizują procesom zakończenie; nie służą tylko do znoszenia zombie. W powyższym pierwszym bloku kodu, jeśli 'wyniki' jest puste, nigdy nie kończymy pracowników, po prostu' zwracasz' do kodu, który był wywołujący. – justinpawela

Odpowiedz

10

Zwykle najczęstszym problemem jest to, że pula jest tworzona, ale nie jest zamknięta.

Najlepszym sposobem, wiem, aby zagwarantować, że basen jest zamknięty jest użycie try/finally klauzuli:

try: 
    pool = Pool(ncores) 
    pool.map(yourfunction, arguments) 
finally: 
    pool.close() 
    pool.join() 

Jeśli nie chcesz walczyć z multiprocessing, napisałem prosty pakiet o nazwie parmap który owija multiprocessing, aby moje życie (i potencjalnie twoje) było łatwiejsze.

pip install parmap

import parmap 
parmap.map(yourfunction, arguments) 

W sekcji użytkowania parmap:

  • Prosty przykład równolegle:

    import parmap 
    y1 = [myfunction(x, argument1, argument2) for x in mylist] 
    y2 = parmap.map(myfunction, mylist, argument1, argument2) 
    y1 == y2 
    
  • iteracji na liście krotki:

    # You want to do: 
    z = [myfunction(x, y, argument1, argument2) for (x,y) in mylist] 
    z = parmap.starmap(myfunction, mylist, argument1, argument2) 
    
    
    # You want to do: 
    listx = [1, 2, 3, 4, 5, 6] 
    listy = [2, 3, 4, 5, 6, 7] 
    param = 3.14 
    param2 = 42 
    listz = [] 
    for (x, y) in zip(listx, listy): 
        listz.append(myfunction(x, y, param1, param2)) 
    # In parallel: 
    listz = parmap.starmap(myfunction, zip(listx, listy), param1, param2) 
    
+0

Jest to tak wygodne dla programistów, którzy nie chcą radzić sobie z bałaganem związanym z przetwarzaniem wielu plików. – ankits