Pythonではmultiprocessing
モジュールを使うと、プロセスを複数立ち上げて並列処理を行うことができます。
これにより、特にマルチコアプロセッサを搭載したコンピュータで処理速度の向上が見込めます。基本的な使い方をいくつか紹介します。
ということなので今更ながら試してみます。
プロセスの作成と実行
シンプルなパターン
Processに実行する関数を渡す。
argsで引数を渡す。
import multiprocessing
def worker(number):
"""仕事をするワーカー関数"""
print(f'Worker: {number}')
if __name__ == '__main__':
# プロセスのリスト
processes = []
# 5つのプロセスを作成
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
processes.append(p)
p.start()
# 全プロセスの終了を待つ
for p in processes:
p.join()
ちゃんと動いていることがわかる。
引数も使えている。
Worker: 0
Worker: 1
Worker: 2
Worker: 3
Worker: 4
データの共有
プロセス間でデータを共有するパターン
Value や Array などの共有メモリオブジェクトを使用する。
import multiprocessing
def increment(shared_number):
"""共有メモリ内の数値をインクリメントする"""
with shared_number.get_lock():
shared_number.value += 1
if __name__ == '__main__':
# 共有メモリオブジェクトの作成
shared_number = multiprocessing.Value('i', 0) # 'i' は int 型を意味する
# プロセスのリスト
processes = []
# 100個のプロセスを作成し、共有メモリの数値をインクリメント
for _ in range(100):
p = multiprocessing.Process(target=increment, args=(shared_number,))
processes.append(p)
p.start()
# 全プロセスの終了を待つ
for p in processes:
p.join()
print(f'Final value: {shared_number.value}')
ちゃんとプロセス数分インクリメントされている。
Final value: 100
プールを使う
複数のプロセスにタスクを分配するためにプールを使用するパターン
特定数のプロセスでタスクを効率的に実行できる。
from multiprocessing import Pool
def square(number):
return number * number
if __name__ == '__main__':
with Pool(5) as p:
results = p.map(square, range(10))
print(results)
タスクが分配されている様子は正直わからないが、分配されていることであろう。。。
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
まとめ
これまでmultiprocessingを使わずにシングルプロセスで動作させてばかりだったが、状況によっては非同期で実行させたい場合もあるし試してみてためになった。
もっとちゃんと使っていきたい。