概要
multiprocessingで並列処理をする際に引数を複数渡す方法をいつも忘れてしまう。
バージョン情報
- Python 3.7.3
引数を1つだけ渡す
渡す引数が1つの場合はPool.mapやPool.imapでiterableな引数を渡すことが多い。
import time from multiprocessing import Pool def sleep(sec): print('start', sec) time.sleep(sec) print('end', sec) with Pool(3) as pool: pool.map(sleep, range(1, 4)) # 同時にstartして順に終わる #=> start 1 #=> start 2 #=> start 3 #=> end 1 #=> end 2 #=> end 3
Processで複数の引数を渡す
Processを使えばだいたいのことはできる。けど管理が面倒。
from multiprocessing import Process def sleep(sec, arg): print('start', sec, arg) time.sleep(sec) print('end', sec, arg) processes = [ Process(target=sleep, args=(i, 'hoge')) for i in range(1, 4)] for p in processes: p.start() for p in processes: p.join() #=> start 1 hoge #=> start 2 hoge #=> start 3 hoge #=> end 1 hoge #=> end 2 hoge #=> end 3 hoge
apply_async
apply_asyncは値が渡しやすく管理も比較的楽。
with Pool(3) as pool: sleeps = [pool.apply_async(sleep, (i, 'hoge')) for i in range(1, 4)] [f.get() for f in sleeps] #=> start 1 hoge #=> start 2 hoge #=> start 3 hoge #=> end 1 hoge #=> end 2 hoge #=> end 3 hoge
starmap
starmapは [(1, 'foo'), (2, 'hoge')] のような値を渡すと、1つ目の実行には 1, 'foo' が、2つ目の実行には 2, 'hoge' が渡される。
下記のような引数を用意する。
list1 = [1, 2, 3] list2 = ['foo', 'bar', 'baz'] args = list(zip(list1, list2)) # => [(1, 'foo'), (2, 'bar'), (3, 'baz')]
starmapで呼び出す。
with Pool(3) as pool: pool.starmap(sleep, args) #=> start 1 foo #=> start 3 baz #=> start 2 bar #=> end 1 foo #=> end 2 bar #=> end 3 baz
改定履歴
Author: Masato Watanabe, Date: 2019-07-20, 記事投稿