Python中,multiprocessing庫中Pool類代表進程池,其對象有imap()和imap_unordered()方法。
兩者都用于對大量數(shù)據(jù)遍歷多進程計算,返回一個迭代器(multiprocessing.pool.IMapIterator)。
imap返回結果順序和輸入相同,imap_unordered則為不保證順序。
經過測試,發(fā)現(xiàn)Python多進程和imap()的一些特性:
1、iter = pool.imap(fn, data)
一旦生成,無論使不使用iter,多進程計算都會開始。
計算結果會緩存在內存中,所以要注意內存用盡的問題。
2、fn,即執(zhí)行函數(shù),不可以是局部對象(不能嵌套在其他函數(shù)里),否則會報錯:
def fn_outer():
def fn(a,b):
return a+b
pool = Pool()
pool.imap(fn, [(1,2)])
pool.close()
AttributeError: Can't pickle local object 'fn_outer.<locals>.fn'
3、使用進程池map數(shù)據(jù)時,如果每次的運算量很小,最后的效率還不如單進程。這時多進程切換造成的開銷已大于多進程計算提升的效率。
這時,可以將輸入數(shù)據(jù)集分段,每次map,計算一段。具體分段多大時獲得最佳效率,需要實際測試。
4、注意,Pool使用完畢后必須關閉,否則進程不會退出。
有兩種寫法,推薦第2種:
注意,第二種中,必須在with的塊內使用iter。
pool = Pool()
iter = pool.imap(func, iter)
for ret in iter:
# do something
pool.close()
with Pool() as pool:
iter = pool.imap(func, iter)
for ret in iter:
# do something