您已经指出了Python2.7文档,因此我将基于Python2.7多处理实现来获得答案.它可能在Python3.X上有所不同,但不应该有很大不同.
apply和apply_async之间的区别
当您查看这些实际上是如何在下面实现时,这两者之间的区别实际上是自我描述.在这里,我将从multiprocessing / pool.py中复制/粘贴代码以用于bot函数.
def apply(self, func, args=(), kwds={}):
'''
Equivalent of `apply()` builtin
'''
assert self._state == RUN
return self.apply_async(func, args, kwds).get()
正如您所看到的,apply实际上是调用apply_async,但在返回结果之前,调用get.这基本上使apply_async阻塞,直到返回结果.
def apply_async(self, func, args=(), kwds={}, callback=None):
'''
Asynchronous equivalent of `apply()` builtin
'''
assert self._state == RUN
result = ApplyResult(self._cache, callback)
self._taskqueue.put(([(result._job, None, func, args, kwds)], None))
return result
apply_async将任务排入任务队列,并返回已提交任务的句柄.使用该句柄,您可以分别调用get或wait来获取结果或等待任务完成.任务完成后,它返回的内容将作为参数传递给回调函数.
例:
from multiprocessing import Pool
from time import sleep
def callback(a):
print a
def worker(i, n):
print 'Entering worker ', i
sleep(n)
print 'Exiting worker'
return 'worker_response'
if __name__ == '__main__':
pool = Pool(4)
a = [pool.apply_async(worker, (i, 4), callback=callback) for i in range(8)]
for i in a:
i.wait()
结果:
Entering worker 0
Entering worker 1
Entering worker 2
Entering worker 3
Exiting worker
Exiting worker
Exiting worker
Exiting worker
Entering worker 4
Entering worker 5
worker_response
Entering worker 6
worker_response
Entering worker 7
worker_response
worker_response
Exiting worker
Exiting worker
Exiting worker
Exiting worker
worker_response
worker_response
worker_response
worker_response
请注意,使用apply_async时,您必须等待结果或等待任务完成.如果你不评论我的例子的最后两行,你的脚本将在你运行后立即完成.
为什么apply_async可能会使用更多进程
我理解这是关于如何描述和工作的.由于apply运行任务将任务发送到池中的可用进程,apply_async将任务添加到队列,然后任务队列线程将它们发送到池中的可用进程.这就是使用apply_async时可能运行多个进程的原因.
我经历了几次this节以更好地理解作者试图传达的想法.让我们在这里检查:
# evaluate "os.getpid()" asynchronously
res = pool.apply_async(os.getpid, ()) # runs in *only* one process
print res.get(timeout=1) # prints the PID of that process
# launching multiple evaluations asynchronously *may* use more processes
multiple_results = [pool.apply_async(os.getpid, ()) for i in range(4)]
print [res.get(timeout=1) for res in multiple_results]
如果我们通过查看前一个示例来尝试理解最后一个示例,当您连续多次调用apply_async时,它肯定可以同时运行更多它们.这可能取决于当时池中使用了多少进程.这就是为什么他们说可能.