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']) Expect all three Finally blocks to be called (or at least, one Finally per x printed by line 8) Actually, only one (occasionally two) are printed. Same behaviour exhibited on dual-core Mac running OSX 10.6 with Python 2.7, and single core Ubuntu running Python 2.6.
Same behavior on Python 3.2 with this code: from multiprocessing import Pool from time import sleep def Process(x): try: print(x) sleep(.6-x/10.) raise Exception('Exception: %d' % x) finally: print('Finally: %d' % x) Pool(3).map(Process, [1, 2, 3])
One might ask why an Exception in one process kills all in the Pool. Perhaps multiprocessing emulates threading too closely. Perhaps it is assumed that if one is bad, all are. Jesse?
As mentioned in http://docs.python.org/dev/library/multiprocessing#multiprocessing.pool.AsyncResult.get “If the remote call raised an exception then that exception will be reraised by get().” map() is just map_async() followed by a get() call on the result. Also, worker processes are called in daemon mode, which explains that children get killed as soon as the parent exits. If you rephrase your example as: try: Pool(3).map(Process, ['1','2','3']) finally: sleep(1) then all the children's finally clauses get a chance to be executed before the parent exits. I would therefore call it "not a bug", although you might add a sentence in the map() documentation stating that an exception is raised as soon as one of the worker fails.