Python: multiprocessing.map: If one process raises an exception, why aren't other processes' finally blocks called?

后端 未结 3 1500
灰色年华
灰色年华 2021-02-01 04:12

My understanding is that finally clauses must *always* be executed if the try has been entered.

import random         


        
3条回答
  •  耶瑟儿~
    2021-02-01 04:47

    The answer from unutbu definitely explains why you get the behavior you observe. However, it should emphasized that SIGTERM is sent only because of how multiprocessing.pool._terminate_pool is implemented. If you can avoid using Pool, then you can get the behavior you desire. Here is a borrowed example:

    from multiprocessing import Process
    from time import sleep
    import random
    
    def f(x):
        try:
            sleep(random.random()*10)
            raise Exception
        except:
            print "Caught exception in process:", x
            # Make this last longer than the except clause in main.
            sleep(3)
        finally:
            print "Cleaning up process:", x
    
    if __name__ == '__main__':
        processes = []
        for i in range(4):
            p = Process(target=f, args=(i,))
            p.start()
            processes.append(p)
        try:
            for process in processes:
                process.join()
        except:
            print "Caught exception in main."
        finally:
            print "Cleaning up main."
    

    After sending a SIGINT is, example output is:

    Caught exception in process: 0
    ^C
    Cleaning up process: 0
    Caught exception in main.
    Cleaning up main.
    Caught exception in process: 1
    Caught exception in process: 2
    Caught exception in process: 3
    Cleaning up process: 1
    Cleaning up process: 2
    Cleaning up process: 3
    

    Note that the finally clause is ran for all processes. If you need shared memory, consider using Queue, Pipe, Manager, or some external store like redis or sqlite3.

提交回复
热议问题