並列処理したい重たい関数processがあるとして、かつその関数が二つ引数をとるときの例。
ここでのprocess関数は、引数に渡されたスリープする時間sleep_timeの秒数待機したのち、インデックスiとセットでコンソールにコメントを出力する。
multi_process関数は並列処理対象のデータ配列を受け取り、Executor オブジェクトに個々の呼び出しをスケジュールして、submitの結果であるfutureオブジェクトをリストにまとめてfutures.waitで完了を待機する。
processの処理内容と引数の形をカスタマイズして使う。
コード
import concurrent.futures
from datetime import datetime as dt
from time import sleep
def main():
# test & sample code
testdata = [ 3, 4, 5, 6, 7] # スリープ時間のリスト
multi_process(testdata)
# 並列処理したい関数
def process(index, sleep_time):
sleep(sleep_time)
print(dt.now().isoformat() + " finish i:" + str(index) + " sleep_time:" + str(sleep_time))
# 並列呼び出しする関数
def multi_process(data):
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = []
for i in range(len(data)):
# Executor オブジェクトに関数実行をスケジュールして、submitの結果であるfutureオブジェクトをリストにとっておく
print(dt.now().isoformat() + " call i:" + str(i))
futures.append(executor.submit(process, i, data[i])) # 個別の呼び出し引数をセット
# それぞれのfutureが処理完了するのを待つ
concurrent.futures.wait(futures)
if __name__ == "__main__":
main()
出力
このコードのmain関数から呼び出すと以下のように、処理が並列に走っているのがわかる。
2024-01-24T11:46:26.539336 call i:0
2024-01-24T11:46:26.542306 call i:1
2024-01-24T11:46:26.545303 call i:2
2024-01-24T11:46:26.548306 call i:3
2024-01-24T11:46:26.550302 call i:4
2024-01-24T11:46:29.544439 finish i:0 sleep_time:3
2024-01-24T11:46:30.546876 finish i:1 sleep_time:4
2024-01-24T11:46:31.549683 finish i:2 sleep_time:5
2024-01-24T11:46:32.552016 finish i:3 sleep_time:6
2024-01-24T11:46:33.555017 finish i:4 sleep_time:7