2017-04-21 1 views
1

Ich bin mit Multiprozessing in Python spielen. Ich versuche, um zu bestimmen, was dann geschieht, wenn ein Arbeiter eine Ausnahme auslösen, damit ich den folgenden Code geschrieben:Ausnahmen in Worker-Prozess

def a(num): 
    if(num == 2): 
     raise Exception("num can't be 2") 
    print(num) 


    p = Pool() 
    p.map(a, [2, 1, 3, 4, 5, 6, 7, 100, 100000000000000, 234, 234, 5634, 0000]) 

Ausgang

3 
4 
5 
7 
6 
100 
100000000000000 
234 
234 
5634 
0 
multiprocessing.pool.RemoteTraceback: 
""" 
Traceback (most recent call last): 
    File "/usr/lib/python3.5/multiprocessing/pool.py", line 119, in worker 
    result = (True, func(*args, **kwds)) 
    File "/usr/lib/python3.5/multiprocessing/pool.py", line 44, in mapstar 
    return list(map(*args)) 
    File "<stdin>", line 3, in a 
Exception: Error, num can't be 2 
""" 

The above exception was the direct cause of the following exception: 

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python3.5/multiprocessing/pool.py", line 260, in map 
    return self._map_async(func, iterable, mapstar, chunksize).get() 
    File "/usr/lib/python3.5/multiprocessing/pool.py", line 608, in get 
    raise self._value 
Exception: Error, num can't be 2 

Wenn Sie die Zahlen sehen, die gedruckt wurde „2“ ist nicht da, aber warum ist nicht auch Nummer 1 da?

Hinweis: Ich verwende Python 3.5.2 auf Ubuntu

+1

Es sieht so aus, als ob Sie auf einem 12-Core-System laufen. map() wendet Funktion a() auf 12 Elemente in der Liste an, aber es gibt insgesamt 13 Elemente in der Liste. Da '2' eine Ausnahme auslöst, wird das Programm angehalten, bevor '1' verarbeitet wird. Siehe [diese Antwort] (http://stackoverflow.com/a/26096355), um Ausnahmen zu umbrechen und später zu erhöhen. – pclrk

+0

Pool funktioniert nicht auf diese Weise. Die Anzahl der Worker hängt mit den Kernen zusammen und sollte zwischen n und 2n liegen, wobei n die Anzahl der Kerne ist. Sie könnten so viele Elemente an 'map()' übergeben, pool teilt den Aufruf mit params in den Arbeitern auf, wenn 'chunksize 'param gesetzt ist, ansonsten wählen die Arbeiter ein Element aus der Liste und rufen die Funktion' a() 'auf vorheriger Artikel und so weiter. Bitte lassen Sie mich wissen, wenn ich falsch liege –

Antwort

1

Standardmäßig erstellt Pool eine Reihe von Arbeitnehmern gleich der Anzahl der Kerne. Wenn einer dieser Arbeitsprozesse stirbt, kann er die Arbeit, die ihm zugewiesen wurde, rückgängig machen. Es kann auch Ausgabe in einem Puffer belassen, der nie gelöscht wird.

Das Muster mit .map() ist Ausnahmen in den Arbeitern zu handhaben und einen geeigneten Fehlerwert, da die Ergebnisse des .map() sollen zurückkehrt Eines-zu-eins mit dem Eingang sein.

from multiprocessing import Pool 

def a(num): 
    try: 
     if(num == 2): 
      raise Exception("num can't be 2") 
     print(num, flush=True) 
     return num 
    except Exception as e: 
     print('failed', flush=True) 
     return e 

p = Pool() 
n=100 
results = p.map(a, range(n)) 

print("missing numbers: ", tuple(i for i in range(n) if i not in results)) 

Hier ist eine andere Frage mit guten Informationen über how exceptions propagate in multiprocessing.map workers.