map_async vs apply_async:在这种情况下我应该使用什么

时间:2014-12-15 07:28:53

标签: python multiprocessing

我正在处理一些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?的重复。在问题中,答案集中在使用这两个函数可以获得的结果的顺序。我在这里问:没有任何东西返回时有什么区别?

2 个答案:

答案 0 :(得分:12)

我建议map_async有三个原因:

  1. 它看起来更整洁的代码。这样:

    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()
    
  2. 使用apply_async,如果post_processing_0.main内发生异常,除非您在失败的{{1}上明确调用P['process_x'].get(),否则您将无法了解它} object,需要遍历所有AsyncResult。使用P时,如果您调用map_async,则会引发异常 - 无需迭代。

  3. async_result.get()具有内置的分块功能,如果map_async非常大,这将使您的代码表现得更好。

  4. 除此之外,如果您不关心结果,行为基本相同。

答案 1 :(得分:9)

apply_async向池中提交单个作业。 map_async使用不同的参数提交多个调用相同函数的作业。前者采用函数加参数列表;后者采用函数加迭代(即序列)来表示参数。 map_async只能调用一元函数(即函数采用一个参数)。

在您的情况下,最好稍微重新构建代码,将所有参数放在一个列表中,然后使用该列表调用map_async一次。