Python は並列複数入力タスクを実装します
1. 問題の説明
- 数万のデータを処理する
- データ処理タスクには複数の入力があります
2、解決策
Pool.starmap_async() または Pool.starmap()を使用し、ニーズに応じて選択できます。
1. Pool.starmap_async()とPool.starmap()の関数
- プロセスプールを作成します。プロセスプールには複数のプロセスが存在します。複数のプロセスがタスクを並行して実行することで、タスクの処理時間を短縮できます。
2. Pool.starmap() と Pool.starmap_async() の違い
- 同じ点
- starmap_async() と starmap() はどちらも、プロセス プール内の関数を呼び出す複数の引数を持つタスクを発行するために使用できます。(starmap_async() と starmap() の両方を使用して、複数の引数を指定してプロセス プール内の関数を呼び出すタスクを発行できます。)
- 違い
- starmap_async() 関数はブロックしませんが、starmap() 関数はブロックします。
- starmap_async() 関数は AsyncResult を返しますが、starmap() 関数はターゲット関数の戻り値の反復可能なオブジェクトを返します。
- starmap_async() 関数は戻り値とエラーに対してコールバック関数を実行できますが、starmap() 関数はコールバック関数をサポートしません。
3. プロセスプール内のインスタンス Pool.starmap() および Pool.starmap_async() の使用方法
1. タスク処理機能を定義する
from random import random
from time import sleep
from multiprocessing.pool import Pool
import multiprocessing
import time, datetime
# task executed in a worker process
def task(x, y):
t1 = str(datetime.datetime.now())[11:]
z = x*y
sleep(1) # block for a moment
t2 = str(datetime.datetime.now())[11:]
# report a message
identifier = multiprocessing.current_process().name
print(f'Task {
identifier}, start time: {
t1}, end time: {
t2}', flush=True)
# return the generated value
return z
2. Pool.starmap_async() は、タスクを並行して実行するプロセス プールを定義および構成します。
# create and configure the process pool
with Pool() as pool:
# prepare arguments
items = [(i, random()) for i in range(10)]
# issues tasks to process pool
result = pool.starmap_async(task, items)
# iterate results
for result in result.get():
print(f'Got result: {
result}', flush=True)
# process pool is closed automatically
3. Pool.starmap() は、タスクを並行して実行するプロセス プールを定義および構成します。
# create and configure the process pool
with Pool() as pool:
# prepare arguments
items = [(i, random()) for i in range(10)]
# issues tasks to process pool
result = pool.starmap_async(task, items)
print(result)
# process pool is closed automatically
4. 結果のテストと分析
-
タスクテストをシリアルに実行する
if __name__ == '__main__': t1 = time.time() items = [(i, random()) for i in range(10)] for item in items: z = task(item[0], item[1]) t2 = time.time() print(f'Done. ({ (1E3 * (t2 - t1)):.1f}ms) Process.')
実行時間time=10014.4 ms の場合、結果は次のようになります。
Task MainProcess, start time: 13:25:41.896662, end time: 13:25:42.897968 Task MainProcess, start time: 13:25:42.898297, end time: 13:25:43.899823 Task MainProcess, start time: 13:25:43.900057, end time: 13:25:44.900915 Task MainProcess, start time: 13:25:44.901269, end time: 13:25:45.902550 Task MainProcess, start time: 13:25:45.902764, end time: 13:25:46.904421 Task MainProcess, start time: 13:25:46.904628, end time: 13:25:47.905779 Task MainProcess, start time: 13:25:47.905974, end time: 13:25:48.906658 Task MainProcess, start time: 13:25:48.906912, end time: 13:25:49.908484 Task MainProcess, start time: 13:25:49.908724, end time: 13:25:50.910294 Task MainProcess, start time: 13:25:50.910528, end time: 13:25:51.910837 Done. (10014.4ms) Process.
-
タスクテストを並行して実行する
-
Pool.starmap_async() は 4 つのプロセスを並列に設定します
# protect the entry point if __name__ == '__main__': t1 = time.time() # create and configure the process pool with Pool(processes=4) as pool: # prepare arguments items = [(i, random()) for i in range(10)] # issues tasks to process pool result = pool.starmap_async(task, items) # iterate results for result in result.get(): print(f'Got result: { result}', flush=True) # process pool is closed automatically t2 = time.time() print(f'Done. ({ (1E3 * (t2 - t1)):.1f}ms) Process.')
実行時間 time=3027.1ms、結果は次のようになります。
Task ForkPoolWorker-4, start time: 13:33:24.838418, end time: 13:33:25.839684 Task ForkPoolWorker-3, start time: 13:33:24.838547, end time: 13:33:25.839684 Task ForkPoolWorker-2, start time: 13:33:24.838292, end time: 13:33:25.839684 Task ForkPoolWorker-1, start time: 13:33:24.838231, end time: 13:33:25.839684 Task ForkPoolWorker-3, start time: 13:33:25.840190, end time: 13:33:26.841160 Task ForkPoolWorker-2, start time: 13:33:25.840530, end time: 13:33:26.841349 Task ForkPoolWorker-1, start time: 13:33:25.840703, end time: 13:33:26.841380 Task ForkPoolWorker-4, start time: 13:33:25.840296, end time: 13:33:26.841381 Task ForkPoolWorker-3, start time: 13:33:26.841865, end time: 13:33:27.842449 Task ForkPoolWorker-2, start time: 13:33:26.841977, end time: 13:33:27.843139 Got result: 0.0 Got result: 0.07020127371886742 Got result: 1.1256784597006964 Got result: 1.5461355349791022 Got result: 0.8560855815072403 Got result: 3.882912015620671 Got result: 1.7547963496144667 Got result: 1.0103926687967728 Got result: 4.760893202587357 Got result: 4.2627716915139695 Done. (3027.1ms) Process.
-
Pool.starmap() は 4 つのプロセスを並列に設定します
# protect the entry point if __name__ == '__main__': t1 = time.time() # create and configure the process pool with Pool(processes=4) as pool: # prepare arguments items = [(i, random()) for i in range(10)] # issues tasks to process pool result = pool.starmap(task, items) print(result) # process pool is closed automatically t2 = time.time() print(f'Done. ({ (1E3 * (t2 - t1)):.1f}ms) Process.')
実行時間 time=3026.7ms、結果は次のようになります。
Task ForkPoolWorker-1, start time: 13:41:59.417044, end time: 13:42:00.418067 Task ForkPoolWorker-4, start time: 13:41:59.417248, end time: 13:42:00.418067 Task ForkPoolWorker-2, start time: 13:41:59.417206, end time: 13:42:00.418067 Task ForkPoolWorker-3, start time: 13:41:59.417213, end time: 13:42:00.418067 Task ForkPoolWorker-4, start time: 13:42:00.418833, end time: 13:42:01.419987 Task ForkPoolWorker-2, start time: 13:42:00.419155, end time: 13:42:01.420250 Task ForkPoolWorker-1, start time: 13:42:00.419356, end time: 13:42:01.420633 Task ForkPoolWorker-3, start time: 13:42:00.419487, end time: 13:42:01.420784 Task ForkPoolWorker-4, start time: 13:42:01.420545, end time: 13:42:02.421670 Task ForkPoolWorker-2, start time: 13:42:01.421409, end time: 13:42:02.422508 [0.0, 0.22916987317496185, 1.48514094188553, 2.6743708768075924, 1.5402186086037761, 4.265952360897589, 0.8526580381048074, 3.806662622060956, 0.8377934521648509, 6.092057694481896] Done. (3026.7ms) Process.
-
-
詳細については、「Python の Multiprocessing Pool.starmap_async()」を参照してください。