2017-05-05 6 views
2

Wenn ich mit Multiprocessing-Pool ausgeführt werde, finde ich, dass der Worker-Prozess über einen Punkt hinausläuft, wo eine Ausnahme ausgelöst wird.Python-Multiprozessing beendet nicht auf Basis Ausnahme

Betrachten Sie den folgenden Code ein:

import multiprocessing 


def worker(x): 
    print("input: " + x) 
    y = x + "_output" 
    raise Exception("foobar") 
    print("output: " + y) 
    return(y) 


def main(): 

    data = [str(x) for x in range(4)] 
    pool = multiprocessing.Pool(1) 
    chunksize = 1 
    results = pool.map(worker, data, chunksize) 
    pool.close() 
    pool.join() 

    print("Printing results:") 
    print(results) 


if __name__ == "__main__": 
    main() 

Die Ausgabe lautet:

$ python multiprocessing_fail.py 
input: 0 
input: 1 
input: 2 
Traceback (most recent call last): 
input: 3 
    File "multiprocessing_fail.py", line 25, in <module> 
    main() 
    File "multiprocessing_fail.py", line 16, in main 
    results = pool.map(worker, data, 1) 
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map 
    return self.map_async(func, iterable, chunksize).get() 
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get 
    raise self._value 
Exception: foobar 

Wie Sie sehen können, der Arbeitsprozess geht nie über raise Exception("foobar") in die zweite print-Anweisung. Zu Beginn von function worker() wird die Arbeit jedoch immer wieder fortgesetzt.

Ich suchte nach einer Erklärung in der Dokumentation, konnte aber keine finden. Hier ist eine potenziell im Zusammenhang SO Frage:

Keyboard Interrupts with python's multiprocessing Pool

Aber das ist anders (über Tastatur-Interrupts nicht durch den Master-Prozess aufgenommen werden).

Eine andere Frage SO:

How to catch exceptions in workers in Multiprocessing

Diese Frage ist auch anders, da darin der Master-Prozess jede Ausnahme doesnt zu fangen, während hier der Master die Ausnahme (Linie 16) fangen haben. Noch wichtiger ist, dass der Arbeiter in dieser Frage nicht über eine Ausnahme hinausgelaufen ist (es gibt nur eine ausführbare Linie für den Arbeiter).

Am laufenden Python 2,7

+3

Mögliche Duplikat von [Wie fangen Ausnahmen bei Arbeitern in Multi] (http://stackoverflow.com/questions erwarten/22094852/how-to-catch-Ausnahmen-in-Worker-in-Multiprocessing) – jordanm

+0

@jordanm danke für die schnelle Antwort! Ich habe diese Frage gelesen und fand sie anders als meine. Bearbeitet um Unterschiede hervorzuheben. – akshan

+0

Es scheint nicht ausgeführt zu werden, hat die Ausnahme bestanden. Die Zeichenkette "output:" wird nie gedruckt. Es scheint, dass nachdem die Ausnahme ausgelöst wird und sie stirbt, sie nur einen neuen Arbeiter hervorbringt. – jordanm

Antwort

0

Kommentar: Pool sollte einen Arbeiter beginnen, da der Code Pool = multiprocessing.Pool (1).

Vom Documnentation:
Verfahren Pool Objekt, das einen Pool von Arbeitsprozessen steuert auf die Arbeitsplätze können


Kommentar eingereicht werden: Dieser eine Worker führt die Funktion worker() mehrfach aus mal

Aus der Dokumentation:
map(func, iterable[, chunksize])
Diese Methode hackt die iterable in eine Reihe von Stücken, die es dem Prozess Pool als getrennte Aufgaben einreicht.

Ihre worker() ist die separate Aufgabe. Umbenennen Sie Ihre worker() zu task() könnte helfen zu klären, was ist was.

Kommentar: Was ich erwarte, ist, dass der Arbeitsprozess an der Exception stürzt

Es tut, der separate Aufgabe, Ihre worker() Gesenke und Pool startet die nächste Aufgabe.

Was Sie wollen, ist Pool.terminate()

Aus der Dokumentation:

terminate()
Stoppt die Arbeitsprozesse sofort ohne herausragende Arbeit abgeschlossen ist.


Frage: ... Ich finde, dass der Arbeitsprozess läuft vorbei an einem Punkt hält, wo eine Ausnahme ausgelöst wird.

Sie geben iteration data-Pool, therfore Pool tut, was es zu tun haben:
Ab len (Daten) Arbeiter.

data = [str(x) for x in range(4)] 

Die Haupt Frage ist: Was wollen Sie mit

raise Exception("foobar") 
+0

Pool sollte einen Worker starten, da der Code 'pool = multiprocessing.Pool (1)' hat. Dieser eine Worker führt die Funktion worker() mehrmals aus (und trifft die Ausnahme auch mehrfach). Ich erwarte, dass der Worker-Prozess bei der Ausnahme abstürzt, da es eine nicht behandelte Ausnahme ist. Leider sagt die Dokumentation nichts über diese Situation aus. – akshan

+0

Kommentar: Pool sollte einen Worker starten, da der Code pool = multiprocessing.Pool (1) hat. Aus der Dokumenation: 'Ein Prozesspool-Objekt, das einen Pool von Worker-Prozessen steuert, an die Jobs übergeben werden können.' Von der nächsten Zeile in der Dokumentation: ' Prozesse ist die Anzahl der Arbeitsprozesse und der Aufruf use.': 'Klasse multiprocessing.Pool ([Prozesse [, initializer [, initargs [, maxtasksperchild ]]]]) '. So sollte genau ein Arbeiter beginnen – akshan

+0

Kommentar: Es tut, die separate Aufgabe, Ihre Worker() stirbt und Pool startet die nächste Aufgabe. Die Funktion worker() ist ein Funktionsobjekt und kann nicht sterben. Ein Prozess kann sterben. Die Tatsache, dass der Arbeitsprozess (wie Sie darauf hingewiesen haben, anders als die Worker() -Funktion) nicht stirbt, ist die Hauptfrage. – akshan

Verwandte Themen