多进程中map_async函数中的回调函数是如何工作的?

35

我花了整整一夜的时间调试代码,最终发现了这个棘手的问题。请查看下面的代码。

from multiprocessing import Pool

def myfunc(x):
    return [i for i in range(x)]

pool=Pool()

A=[]
r = pool.map_async(myfunc, (1,2), callback=A.extend)
r.wait()
我以为会得到A=[0,0,1],但输出结果是A=[[0],[0,1]]。对我来说这没有意义,因为如果有A=[]A.extend([0])A.extend([0,1]) 将给我 A=[0,0,1]。可能回调函数的工作方式不同。所以我的问题是如何获得A=[0,0,1]而不是[[0],[0,1]]

你使用的操作系统和Python版本是什么? - Games Brainiac
1个回答

48

如果您使用map_async,回调函数将被调用一次并返回结果([[0], [0, 1]])。

>>> from multiprocessing import Pool
>>> def myfunc(x):
...     return [i for i in range(x)]
... 
>>> A = []
>>> def mycallback(x):
...     print('mycallback is called with {}'.format(x))
...     A.extend(x)
... 
>>> pool=Pool()
>>> r = pool.map_async(myfunc, (1,2), callback=mycallback)
>>> r.wait()
mycallback is called with [[0], [0, 1]]
>>> print(A)
[[0], [0, 1]]

如果您希望对每个任务调用回调函数,请使用apply_async

pool=Pool()
results = []
for x in (1,2):
    r = pool.apply_async(myfunc, (x,), callback=mycallback)
    results.append(r)
for r in results:
    r.wait()

2
这段代码不应该起作用,你需要将它放在一个 if __name__ == '__main__' 语句下面。 - Games Brainiac
16
@GamesBrainiac,在Windows系统中使用Python多进程模块的相关文档链接为:http://docs.python.org/2/library/multiprocessing.html#windows。 - falsetru
2
哦!那我很抱歉。你们这些幸运的Mac/Linux用户 :P - Games Brainiac
1
@falsetru,它运行了。谢谢你。现在我看到 apply_async 和 map_async 之间另一个区别。 - user2727768
使用放置 if __name__ == '__main__' 可以使其在 Windows 以及其他操作系统中工作,因此我建议始终以这种方式进行改进可移植性。 - martineau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接