Exception thrown in multiprocessing Pool not detected

后端 未结 9 831
灰色年华
灰色年华 2020-11-29 18:44

It seems that when an exception is raised from a multiprocessing.Pool process, there is no stack trace or any other indication that it has failed. Example:

         


        
9条回答
  •  忘掉有多难
    2020-11-29 19:31

    The solution with the most votes at the time of writing has a problem:

    from multiprocessing import Pool
    
    def go():
        print(1)
        raise Exception("foobar")
        print(2)
    
    p = Pool()
    x = p.apply_async(go)
    x.get()  ## waiting here for go() to complete...
    p.close()
    p.join()
    

    As @dfrankow noted, it will wait on x.get(), which ruins the point of running a task asynchronously. So, for better efficiency (in particular if your worker function go takes a long time) I would change it to:

    from multiprocessing import Pool
    
    def go(x):
        print(1)
        # task_that_takes_a_long_time()
        raise Exception("Can't go anywhere.")
        print(2)
        return x**2
    
    p = Pool()
    results = []
    for x in range(1000):
        results.append( p.apply_async(go, [x]) )
    
    p.close()
    
    for r in results:
         r.get()
    

    Advantages: the worker function is run asynchronously, so if for example you are running many tasks on several cores, it will be a lot more efficient than the original solution.

    Disadvantages: if there is an exception in the worker function, it will only be raised after the pool has completed all the tasks. This may or may not be the desirable behaviour. EDITED according to @colinfang's comment, which fixed this.

提交回复
热议问题