Python のマルチプロセッシング Pool.starmap_async() および Pool.starmap() は、並列複数入力タスクを実装します。

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()」を参照してください。

おすすめ

転載: blog.csdn.net/qq_40541102/article/details/130641350