2017-06-16 3 views
1

Ich verwende Python-Multiprocessing, um einen der längeren Prozesse zu teilen und parallel zu laufen. Es funktioniert gut, außer wenn in einem der untergeordneten Prozesse eine Ausnahme vorliegt. In diesem Fall wird der Prozesspool nicht geschlossen und ich kann diese Prozesse weiterhin auf dem Server sehen.Python Multiprocessing: So schließen Sie den Multiprocessing-Pool auf Ausnahme

Hier ist der Code:

from multiprocessing import Pool 
pool = Pool(processes=4) 
from functools import partial 
param_data = "Test Value" 
func = partial(test_function, param_data) 
r = pool.map(func, range(3)) 
pool.close() 

def test_function(param_data,index): 
    try: 
     # The process here; 
    except Exception as e: 
     # Close the process pool; 

Auf pool.close innerhalb der except-Block geben, sagt er

NameError: global name 'pool' is not defined

ich den Prozess auf Ausnahme mit dem folgenden Code zu töten versucht.

except Exception as e: 
     import os 
     import signal 
     pid = os.getpid() 
     os.kill(pid, signal.SIGTERM) 

Aber ich kann immer noch den Prozess auf dem Server sehen. Dies ist immer noch nicht die beste Lösung, da dies nur den Child-Prozess beendet, der eine Ausnahme vorfindet. Andere Prozesse werden trotzdem weitergehen.

Ich möchte alle Prozesse bei Abschluss beenden, unabhängig davon, ob sie mit einer Ausnahme auftreten oder nicht.

Ich bin mit python2.7

Ps: Ich kann nicht eine neue Bibliothek wie psutil auf dem Server installieren, bin ich für eine Lösung versucht, Standard-Python-Bibliothek.

Ich überprüfte einige ähnliche Fragen wie, auto kill process and child in diesem Forum, aber sie waren nicht wirklich dieses Problem.

+1

Haben Sie versucht, die Ergebnisse mit 'r.get()' zu erhalten, bevor Sie 'pool.close()' aufrufen? Ich denke, die Prozesse werden nicht beendet, bevor Sie ihre Ergebnisse nach dem Aufruf von 'pool.map()' erhalten. Oh, und Sie sollten nicht versuchen, das "Pool" -Objekt von untergeordneten Prozessen zu berühren, wie in der Dokumentation steht: 'Beachten Sie, dass die Methoden eines Pools nur von dem Prozess verwendet werden sollten, der sie erstellt hat. – Maciek

+0

Danke @Maciek, Ich habe die Lösung, indem ich den gesamten Prozesscode des Elternteils innerhalb von try ... außer Block. Teilen Sie es als Antwort unten. – Codeformer

Antwort

1

Ich habe die Lösung dafür - Catch Ausnahme im übergeordneten Prozess.

try: 
    pool = Pool(processes=4) 
    from functools import partial 
    param_data = "Test Value" 
    func = partial(test_function, param_data) 
    r = pool.map(func, range(3)) 
except Exception as e: 
    pool.close() 
pool.close() 

Und in der Kind-Prozess-Funktion:

def test_function(param_data,index): 
try: 
    # The process here; 
except Exception as e: 
    raise Exception(e.message) 

Die except-Block sieht hier überflüssig, aber es ist nicht. Der Grund dafür ist, dass einige der Ausnahmen, die vom untergeordneten Prozess ausgelöst wurden, nicht in den übergeordneten Prozess übertragen wurden. Zum Beispiel habe ich eine benutzerdefinierte Ausnahme in der Funktion ausgelöst, und es wurde nicht in den Elternprozess geworfen. Daher ist es ratsam, alle Ausnahmen innerhalb des Kindprozesses abzufangen und die Standard Exception von dort anzuheben Sie können den Prozesspool schließen oder andere Bereinigungen durchführen.