python进程池之创建子任务的函数总结

目录

map

apply

map_async和apply_async

imap和imap_unordered

starmap和starmap_async


    

        python多进程标准库multiprocessing通过进程池启动多进程有以下几种方式,本文旨在说明这几种方式的区别:map、apply、map_async、apply_async、imap、imap_unordered、starmap、starmap_async。

map

map函数签名:map(func, iterable[, chunksize])

        从函数签名来看,map会自动将func函数依次应用在iterable中的每个参数上,从而会产生多个并行的func任务,同时有多少个任务在并行取决于在创建进程池时指定了多少个进程(这里并不是进程在多个任务之间频繁切换以使得所有任务并发进行,而是一个进程处理完一个任务后再依次进行下一个)。map的多个子任务中,一旦有一个出现了异常,那么所有的结果将无法获取,但是其他子任务会正常运行(如果chunksize不为1,那么以chunk为单位,某个chunk出现异常,该chunk会立即停止,但其他chunk会正常运行,只是依然无法获取结果)。

        如果map函数设置了chunksize,那么map会把iterable参数进行等分,每份的大小等于 chunksize,需要注意的是,每个chunk会分配给一个进程顺序执行,这可能导致进程池中某个进程实际上已经处理完自己的chunk处于闲置状态了,但是并不能获取其他进程还未处理完的chunk中的任务,导致这些提早结束的进程处于闲置状态,浪费资源。当然,如果不设置chunksize参数,那么默认是对iterable中的参数逐个处理,即chunksize等于1,这样一旦有进程处理完某个任务后,会立即获取下一个参数继续处理,不会处于闲置状态;但是这样的缺陷就是,如果iterable参数过长,会导致频繁的给进程切换上下文,降低效率,而设定chunksize将参数一次传给进程可以避免频繁切换。

        iterable参数过长还可能造成内存消耗过大,因为map会一次性把iterable对应的多个子任务得到的结果保存在一个list中,这样内存中会保存一个很长的list,可能会过多消耗内存。这种情况下,可以使用下面的imap/imap_unordered,再结合chunksize参数,可以显著提升效率。

apply

apply函数签名:apply(func[, args[, kwds]])

        apply只是将func函数作为一个任务添加到进程中并执行,args和kwds是可选的传给func的位置参数和关键字参数,该函数每次只能运行一个任务,结束了之后才能运行下一个任务,因此,apply实际上并不能利用子进程进行多任务并行。     

map_async和apply_async

map_async函数签名:map_async(funciterable[, chunksize[, callback[, error_callback]]])

apply_async函数签名:apply_async(func[, args[, kwds[, callback[, error_callback]]]])

        相比于map和apply,这两个函数不会阻塞主进程。如果在程序中,想要阻塞进行直至任务执行结束,那么可以调用pool的join方法,该方法会阻塞子进程直至所有任务结束;要注意的是,在调用join方法之前,需要先调用pool的close方法,表示任务添加完毕,这样join才被允许调用。

        这两个函数都会返回AsyncResult对象,AsyncResult对象的get函数可以获取运行结果。对于map_async函数,AsyncResult对象的get函数得到的是一个包含了多个任务运行结果的列表,而且结果的顺序和输入的iterable顺序一致。对于apply_async,其对应的AsyncResult的get函数返回的就是func函数返回的结果。

        AsyncResult的get函数会阻塞主进程,直至子进程的任务全部执行完。即map_async(func,iterable).get()等效于map(func,iterable),apply_async(func,args).get()等效于apply(func,args)。

imap和imap_unordered

        imap和map一样,会立即开始并行处理任务,同时进行的任务个数和进程池中的进程数相等,并且处理完某个任务或者chunk后会自动处理下一个,这点和map完全一样。相比于map,区别是imap可以获取先结束的任务的结果进行处理,而不用等到所有任务都执行完毕之后才能处理结果。具体地,imap会返回一个生成器,对多个任务结果进行迭代,即当某个chunk处理完毕之后,这个chunk中的所有任务的结果就可以准备逐一迭代了;当然,如果chunk中只是部分任务执行完毕,还不能进入迭代,需要等chunk中所有任务都完成后再一起进入迭代,这是因为python将一个chunk中的任务打包成一个循环执行的普通任务交给进程,因此这时对进程来说,一个chunk中的任务就是一个任务,只有等这个打包任务全部执行完毕才能获取结果。默认情况下,chunksize是1。

        这里需要注意的是,尽管有些chunk已经执行完毕,但是并不一定可以立马迭代处理,因为imap生成器是对多个chunk的执行结果保序的,因此,某个chunk执行完后,只是可以做好迭代准备,真正对其进行迭代,需要等到该chunk之前的所有chunk或者任务迭代完后,才会轮到其本身。这会带来的一个问题是,如果靠前的chunk要花费很长时间,那么后面已经处理完的chunk需要等到很长时间,这导致了主进程一直阻塞,浪费了时间。对此,可以imap_unordered解决。imap_unordered相比于imap,其不要求生成器的生成顺序保序,只要某个chunk结束返回了结果,迭代器就会立即准备好供主进程迭代并进行下一步处理,而不会因为顺序迭代的原因阻塞在某个chunk上。

starmap和starmap_async

        相比map和map_async,starmap和starmap_async唯一的区别就是要求iterable中的元素也是可迭代的,并将可迭代元素解包成多个位置参数传给func。即如果iterable是[(1,2),(3,4)],那么子任务分别是func(1,2)和func(3,4)。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值