我正在处理一些ascii-data,进行一些操作,然后将所有内容写回另一个文件(由post_processing_0.main
完成的工作,而不返回任何内容)。我想将代码与多处理模块并行化,请参阅以下代码片段:
from multiprocessing import Pool
import post_processing_0
def chunks(lst,n):
return [ lst[i::n] for i in xrange(n) ]
def main():
pool = Pool(processes=proc_num)
P={}
for i in range(0,proc_num):
P['process_'+str(i)]=pool.apply_async(post_processing_0.main, [split_list[i]])
pool.close()
pool.join()
proc_num=8
timesteps=100
list_to_do=range(0,timesteps)
split_list=chunks(list_to_do,proc_num)
main()
我读了地图和异步之间的区别,但我不太了解它。我的多处理模块的应用是否正确?
在这种情况下,我应该使用map_async还是apply_async?为什么?
编辑:
我认为这不是问题Python multiprocessing.Pool: when to use apply, apply_async or map?的重复。在问题中,答案集中在使用这两个函数可以获得的结果的顺序。我在这里问:没有任何东西返回时有什么区别?
答案 0 :(得分:12)
我建议map_async
有三个原因:
它看起来更整洁的代码。这样:
pool = Pool(processes=proc_num)
async_result = pool.map_async(post_processing_0.main, split_list)
pool.close()
pool.join()
看起来比这更好:
pool = Pool(processes=proc_num)
P={}
for i in range(0,proc_num):
P['process_'+str(i)]=pool.apply_async(post_processing_0.main, [split_list[i]])
pool.close()
pool.join()
使用apply_async
,如果post_processing_0.main
内发生异常,除非您在失败的{{1}上明确调用P['process_x'].get()
,否则您将无法了解它} object,需要遍历所有AsyncResult
。使用P
时,如果您调用map_async
,则会引发异常 - 无需迭代。
async_result.get()
具有内置的分块功能,如果map_async
非常大,这将使您的代码表现得更好。
除此之外,如果您不关心结果,行为基本相同。
答案 1 :(得分:9)
apply_async
向池中提交单个作业。 map_async
使用不同的参数提交多个调用相同函数的作业。前者采用函数加参数列表;后者采用函数加迭代(即序列)来表示参数。 map_async
只能调用一元函数(即函数采用一个参数)。
在您的情况下,最好稍微重新构建代码,将所有参数放在一个列表中,然后使用该列表调用map_async
一次。