並列実行のための Python マルチプロセッシング

PythonPythonIntermediate
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

Pythonのマルチプロセッシングは、高い処理能力が必要なPythonプログラムの実行速度を大幅に向上させる強力なツールです。この実験では、Pythonのマルチプロセッシングとそれを使って並列処理を行う方法について学びます。まずは簡単な例から始め、徐々に複雑な例に向かっていきます。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/FileHandlingGroup(["File Handling"]) python(("Python")) -.-> python/AdvancedTopicsGroup(["Advanced Topics"]) python(("Python")) -.-> python/PythonStandardLibraryGroup(["Python Standard Library"]) python(("Python")) -.-> python/BasicConceptsGroup(["Basic Concepts"]) python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python(("Python")) -.-> python/ModulesandPackagesGroup(["Modules and Packages"]) python/BasicConceptsGroup -.-> python/numeric_types("Numeric Types") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/ModulesandPackagesGroup -.-> python/standard_libraries("Common Standard Libraries") python/FileHandlingGroup -.-> python/with_statement("Using with Statement") python/AdvancedTopicsGroup -.-> python/threading_multiprocessing("Multithreading and Multiprocessing") python/PythonStandardLibraryGroup -.-> python/os_system("Operating System and System") subgraph Lab Skills python/numeric_types -.-> lab-7843{{"並列実行のための Python マルチプロセッシング"}} python/function_definition -.-> lab-7843{{"並列実行のための Python マルチプロセッシング"}} python/standard_libraries -.-> lab-7843{{"並列実行のための Python マルチプロセッシング"}} python/with_statement -.-> lab-7843{{"並列実行のための Python マルチプロセッシング"}} python/threading_multiprocessing -.-> lab-7843{{"並列実行のための Python マルチプロセッシング"}} python/os_system -.-> lab-7843{{"並列実行のための Python マルチプロセッシング"}} end

簡単なマルチプロセッシングプログラムの作成

Pythonにおけるマルチプロセッシングを学ぶ最初のステップは、それがどのように機能するかを示す簡単なプログラムを作成することです。このプログラムでは、単一の引数を受け取り、その数の二乗を返す関数を作成します。その後、マルチプロセッシングを使ってこの関数を複数のプロセスで実行します。

square.pyを完成させてください。

import multiprocessing

def square(x):
    return x * x

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=4)
    results = pool.map(square, range(10))
    print(results)

このコードは4つのプロセスのプールを作成し、map()関数を使ってsquare()関数を0から9までの範囲の各数字に適用します。その結果をコンソールに出力します。

マルチプロセッシングを使って処理速度を向上させる

Pythonにおけるマルチプロセッシングの仕組みが理解できたので、もう少し複雑な例に移りましょう。この例では、マルチプロセッシングを使って、非常に大きな数のリストの処理速度を向上させます。

complex_square.pyを完成させてください。

import multiprocessing

def square(x):
    return x * x

if __name__ == '__main__':
    with multiprocessing.Pool(processes=4) as pool:
        results = pool.map(square, range(1000000))
    print(results[:10])

このコードは4つのプロセスのプールを作成し、map()関数を使ってsquare()関数を0から999999までの範囲の各数字に適用します。処理が完了したときにプロセスのプールが適切にクローズされるように、with文を使っています。その後、最初の10個の結果をコンソールに出力します。

プロセス間通信

Pythonでマルチプロセッシングを使用する場合、プロセス間で通信する必要がある場合があります。この例では、multiprocessing.Queue()関数を使用してプロセス間で共有キューを作成します。

multiprocessing_queue.pyを完成させてください。

import multiprocessing

def producer(queue):
    for i in range(10):
        queue.put(i)

def consumer(queue):
    while True:
        item = queue.get()
        if item is None:
            break
        print(item)

if __name__ == '__main__':
    queue = multiprocessing.Queue()
    process_producer = multiprocessing.Process(target=producer, args=(queue,))
    process_consumer = multiprocessing.Process(target=consumer, args=(queue,))
    process_producer.start()
    process_consumer.start()
    process_producer.join()
    queue.put(None)
    process_consumer.join()

このコードはmultiprocessing.Queue()関数を使用して共有キューqueueを作成します。その後、2つのプロセスを作成し、それぞれがproducer()関数とconsumer()関数を呼び出します。producer()関数は0から9までの数字をキューに入れ、consumer()関数はキューから各項目を取得してコンソールに出力します。

Pool.apply_async() による非同期タスク

map() に加えて、multiprocessing.Pool() クラスは並列でプロセスを実行するための別のメソッドである apply_async() を提供します。このメソッドを使用すると、関数呼び出しをプロセスのプールに送信し、結果を待たずに即座に実行を続けることができます。代わりに、関数呼び出しの結果が準備できたときにコールバック関数を使用して結果を取得することができます。

slow_square.py を完成させてください。

import multiprocessing
import time

def slow_square(x):
    time.sleep(1)
    return x * x

def callback(result):
    print(result)

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=4)
    results = [pool.apply_async(slow_square, (x,), callback=callback) for x in range(10)]
    for result in results:
        result.wait()
    print("All tasks completed.")

この例では、数 x を受け取り、1秒待った後に x の二乗を返す関数 slow_square() を定義します。また、利用可能なときに結果を単に表示するコールバック関数 callback() も定義します。

その後、4つのプロセスのプールを作成し、apply_async() を使用して0から9までの範囲の各数に対して関数呼び出しをプールに送信します。args パラメータを使用して slow_square() 関数と引数 x を渡し、結果が準備できたときに呼び出すコールバック関数も指定します。

その後、結果のリストをループして result.wait() を呼び出して、結果が準備できるまでメインスレッドをブロックします。最後に、すべてのタスクが完了したことを示すメッセージを表示します。

まとめ

この実験では、Pythonのマルチプロセッシングを使って並列でプロセスを実行する方法を学びました。まず、マルチプロセッシングがどのように機能するかを示す簡単なプログラムから始め、その後、マルチプロセッシングを使って処理速度を向上させ、プロセス間でメモリを共有し、apply_async()を使って非同期タスクを実行するようなより複雑な例に移りました。この実験が終わるまでに、自分自身のPythonプログラムでマルチプロセッシングをどのように使うかを十分に理解しており、より大きな処理能力と効率を達成し、必要に応じてプロセス間で通信することができるようになっているはずです。