ごく簡単なPython multiprocessingの使い方の話。
例えば次のようなコードがあります。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
import time def calc(x): a = x * 2 print(a) time.sleep(2) if __name__ == '__main__': data = [1, 2, 3, 4, 5] [calc(x) for x in data] |
この処理を、後から並列で実行したくなったとします。(そのような経験があなたにもありますよね?)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import time import multiprocessing def worker(data): [calc(x) for x in data] def calc(x): a = x * 2 print(a) time.sleep(2) if __name__ == '__main__': split_data = [[1, 2, 3], [4, 5]] jobs = [] for data in split_data: job = multiprocessing.Process(target=worker, args=(data, )) jobs.append(job) job.start() [job.join() for job in jobs] print('Finish') |
このコードは、子プロセスを2つ生成して処理を実行します。
処理対象のリスト = data を2分割したものが split_data です。分割はCPUのコア数などに応じて動的に行われるべきですが、本題ではないので手動で分割しています。for文の中身はごく簡単なmultiprocessingの使い方です。targetで指定しているworker()はWrapper的な役割を持たせたメソッドで、新規に追加したものです。
worker()経由で実行するとcalc()に変更を加えなくて良いため、お手軽感があります。
join()を省略するとどうなるでしょうか。
|
1 2 3 4 5 6 |
for data in split_data: job = multiprocessing.Process(target=worker, args=(data, )) jobs.append(job) job.start() print('Finish') |
並列処理が完了する前にprint()が実行されてしまい、後続の処理がある場合問題になります。
joinの位置を以下のようにするとどうなるでしょうか。
|
1 2 3 4 5 6 |
for data in split_data: job = multiprocessing.Process(target=worker, args=(data, )) job.start() job.join() print('Finish') |
start()したプロセスの完了をforの中で待つことになるので、シングルプロセスでの実行と同じになってしまいます。
Social Links