multiprocessing.Pool:何时使用apply,apply_async或map?

我还没有看到使用Pool.apply , Pool.apply_async和Pool.map的例子 。 我主要使用Pool.map ; 别人的优点是什么?

回到过去的Python,用任意参数调用一个函数,你可以使用apply

 apply(f,args,kwargs) 

apply在Python2.7中仍然存在,但不在Python3中,一般不再使用。 如今,

 f(*args,**kwargs) 

是优选的。 multiprocessing.Pool模块试图提供一个类似的接口。

Pool.apply就像Python一样,除了函数调用是在一个独立的进程中执行的。 Pool.apply阻塞,直到函数完成。

Pool.apply_async也像Python的内置apply ,除了调用立即返回,而不是等待结果。 一个ApplyResult对象被返回。 你调用它的get()方法来检索函数调用的结果。 get()方法阻塞,直到函数完成。 因此, pool.apply(func, args, kwargs)等同于pool.apply_async(func, args, kwargs).get()

Pool.apply相反, Pool.apply_async方法也有一个callback函数,如果提供的话,当函数完成时调用。 这可以用来代替调用get()

例如:

 import multiprocessing as mp import time def foo_pool(x): time.sleep(2) return x*x result_list = [] def log_result(result): # This is called whenever foo_pool(i) returns a result. # result_list is modified only by the main process, not the pool workers. result_list.append(result) def apply_async_with_callback(): pool = mp.Pool() for i in range(10): pool.apply_async(foo_pool, args = (i, ), callback = log_result) pool.close() pool.join() print(result_list) if __name__ == '__main__': apply_async_with_callback() 

可能会产生如下结果

 [1, 0, 4, 9, 25, 16, 49, 36, 81, 64] 

注意,与pool.map不同,结果的顺序可能不对应于pool.apply_async调用的顺序。


所以,如果你需要在一个单独的进程中运行一个函数,但是希望当前进程阻塞,直到函数返回,使用Pool.apply 。 像Pool.apply一样, Pool.map阻塞,直到返回完整的结果。

如果希望工作进程池asynchronous执行多个函数调用,请使用Pool.apply_async 。 结果的顺序不能保证与调用Pool.apply_async的顺序相同。

还要注意,你可以用Pool.apply_async调用一些不同的函数(不是所有的调用都需要使用相同的函数)。

相反, Pool.map将相同的函数应用于许多参数。 但是,与Pool.apply_async不同,结果将按照与参数顺序相对应的顺序返回。

关于apply vs map

pool.apply(f, args)f只在池中的一个工作者中执行。 所以池中的一个进程将运行f(args)

pool.map(f, iterable) :这个方法将迭代器切成许多块,并把它作为独立的任务提交给进程池。 所以你利用了池中的所有进程。