Mein Verständnis ist, dass finally-Klauseln müssen *immer* ausgeführt werden, wenn der try-Block betreten wurde.
import random
from multiprocessing import Pool
from time import sleep
def Process(x):
try:
print x
sleep(random.random())
raise Exception('Exception: ' + x)
finally:
print 'Finally: ' + x
Pool(3).map(Process, ['1','2','3'])
Die erwartete Ausgabe ist, dass für jedes x, das auf Zeile 8 einzeln ausgegeben wird, es ein Vorkommen von 'Finally x' geben muss.
Beispiel-Ausgabe:
$ python bug.py
1
2
3
Finally: 2
Traceback (most recent call last):
File "bug.py", line 14, in
Pool(3).map(Process, ['1','2','3'])
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 225, in map
return self.map_async(func, iterable, chunksize).get()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 522, in get
raise self._value
Exception: Exception: 2
Es scheint, dass eine Ausnahme, die einen Prozess beendet, auch den Eltern- und Geschwisterprozess beendet, obwohl in anderen Prozessen noch weitere Arbeit erforderlich ist.
Warum liege ich falsch? Warum ist das korrekt? Wenn dies korrekt ist, wie sollte man Ressourcen sicher in multiprozessiertem Python aufräumen?
0 Stimmen
Nur eine Vorwarnung für andere: Dieser genaue Code (mit korrigierten Druckanweisungen für Python 3) wird in Python 3.6 ordnungsgemäß ausgeführt, bevor der Elternprozess die Ausnahme erneut auslöst.