Pool.imap で引数の関数が実行されるタイミングについてメモ [Python]
Generator を使ったコードを以下に示す.
def get_time(x=None): sleep(1) return datetime.now().time() def generator(): while True: yield get_time() if __name__ == '__main__': it = generator() sleep(5) print(datetime.now().time(), 'Begin') print(next(it)) print(next(it)) print(next(it)) print(datetime.now().time(), 'End')
上記のコードの実行結果は以下のようになる.
12:01:04.985315 Begin 12:01:05.986125 12:01:06.989681 12:01:07.993368 12:01:07.993416 End
get_time
は,呼ぶと1秒待ってから現在時刻を返す.
next(it)
によってget_time
が呼ばれるため,約1秒毎に現在時刻を返す.
Pool.imap
を使ったコードを以下に示す.
ここで呼ばれているget_time
は上記のコードと同様である.
if __name__ == '__main__': with Pool(processes=2) as p: it = p.imap(get_time, [1, 2, 3]) sleep(5) print(datetime.now().time(), 'Begin') print(next(it)) print(next(it)) print(next(it)) print(datetime.now().time(), 'End')
実行結果は以下のようになる.
12:01:13.042683 Begin 12:01:09.043455 12:01:09.043456 12:01:10.044876 12:01:13.043180 End
next(it)
が呼ばれているのはprint(datetime.now().time(), 'Begin')
の後だが,出力された時刻はBegin
の時点より早い.
Generator を使ったコードでは,next(it)
を呼び出した時点でget_time
が呼び出される.
一方で,Pool.imap
を使ったコードでは,Pool.imap
を実行した時点で get_time
が実行され始める.
sleep(5)
で待機している間に,get_time
の三度の呼び出しが非同期で実行され,結果が保持される.
その後の next(it)
では,すでに実行した get_time
の結果を返すだけで,get_time
の実行はされない.