多处理池'apply_async'似乎只调用一次函数

Jui*_*icy 6 python multithreading multiprocessing threadpool

我一直在关注文档以尝试理解多处理池.我想出了这个:

import time
from multiprocessing import Pool

def f(a):
    print 'f(' + str(a) + ')'
    return True

t = time.time()
pool = Pool(processes=10)
result = pool.apply_async(f, (1,))
print result.get()
pool.close()
print ' [i] Time elapsed ' + str(time.time() - t)
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用10个进程来评估函数f(a).我已经打印了一份印刷声明f.

这是我得到的输出:

$ python pooltest.py 
f(1)
True
 [i] Time elapsed 0.0270888805389
Run Code Online (Sandbox Code Playgroud)

在我看来,该功能f只被评估一次.

我可能没有使用正确的方法,但我正在寻找的最终结果是同时运行f10个进程,并获得每个进程返回的结果.所以我最后会列出10个结果(可能相同也可能不相同).

关于多处理的文档非常令人困惑,要弄清楚我应该采用哪种方法并不容易,而且在我看来f应该在我上面提供的示例中运行10次.

Jos*_*lor 8

apply_async并不意味着启动多个进程; 它只是用于在池的一个进程中使用参数调用该函数.如果要将函数调用10次,则需要进行10次调用.

首先,请注意文档apply()(强调添加):

apply(func[, args[, kwds]])
Run Code Online (Sandbox Code Playgroud)

使用参数args和关键字参数kwds调用func.它会阻塞,直到结果准备就绪.给定此块,apply_async()更适合并行执行工作.此外,func仅在池中的一个工作程序中执行.

现在,在以下文档中apply_async():

apply_async(func[, args[, kwds[, callback[, error_callback]]]])
Run Code Online (Sandbox Code Playgroud)

apply()方法的一种变体,它返回一个结果对象.

两者之间的区别仅在于apply_async立即返回.您可以使用map()多次调用函数,但是如果您使用相同的输入进行调用,那么创建相同参数的列表只是为了获得正确长度的序列,这有点减少.

但是,如果您使用相同的输入调用不同的函数,那么您实际上只是调用更高阶函数,并且可以使用map或者map_async()像这样:

multiprocessing.map(lambda f: f(1), functions)
Run Code Online (Sandbox Code Playgroud)

除了lambda函数不是pickleable之外,所以你需要使用一个已定义的函数(参见如何让Pool.map获取lambda函数).你实际上可以使用内置的apply()(不是多处理的)(虽然它已被弃用):

multiprocessing.map(apply,[(f,1) for f in functions])
Run Code Online (Sandbox Code Playgroud)

编写自己的也很容易:

def apply_(f,*args,**kwargs):
  return f(*args,**kwargs)

multiprocessing.map(apply_,[(f,1) for f in functions])
Run Code Online (Sandbox Code Playgroud)