Concurrency-in-python-pool-of-processes
Pythonの同時実行-プロセスのプール
プロセスのプールは、スレッドのプールを作成して使用したのと同じ方法で作成して使用できます。 プロセスプールは、事前にインスタンス化されたプロセスとアイドルプロセスのグループとして定義できます。 多数のタスクを実行する必要がある場合、すべてのタスクの新しいプロセスをインスタンス化するよりもプロセスプールを作成することをお勧めします。
Pythonモジュール– Concurrent.futures
Python標準ライブラリには、 concurrent.futures というモジュールがあります。 このモジュールは、非同期タスクを起動するための高レベルインターフェイスを開発者に提供するために、Python 3.2で追加されました。 これは、スレッドまたはプロセスのプールを使用してタスクを実行するためのインターフェースを提供するためのPythonのスレッド化およびマルチプロセッシングモジュールの上部にある抽象化レイヤーです。
以降のセクションでは、concurrent.futuresモジュールのさまざまなサブクラスを見ていきます。
エグゼキュータークラス
- ThreadPoolExecutor
- ProcessPoolExecutor
ProcessPoolExecutor –具体的なサブクラス
これは、Executorクラスの具象サブクラスの1つです。 マルチプロセッシングを使用し、タスクを送信するためのプロセスのプールを取得します。 このプールは、利用可能なプロセスにタスクを割り当て、実行するようにスケジュールします。
ProcessPoolExecutorを作成する方法は?
例
ここで、スレッドプールの作成時に使用したのと同じ例を検討します。唯一の違いは、 ThreadPoolExecutor の代わりに ProcessPoolExecutor を使用することです。
出力
上記の例では、Process * PoolExecutor は5つのスレッドで構成されています。 次に、メッセージを出す前に2秒間待機するタスクがプロセスプールエグゼキューターに送信されます。 出力からわかるように、タスクは2秒まで完了しないため、 done()の最初の呼び出しはFalseを返します。 2秒後、タスクは完了し、 result()*メソッドを呼び出して未来の結果を取得します。
ProcessPoolExecutorのインスタンス化–コンテキストマネージャー
ProcessPoolExecutorをインスタンス化する別の方法は、コンテキストマネージャーを使用することです。 上記の例で使用した方法と同様に機能します。 コンテキストマネージャを使用する主な利点は、構文的に見た目が良いことです。 インスタンス化は、次のコードの助けを借りて行うことができます-
例
理解を深めるために、スレッドプールの作成時に使用したのと同じ例を取り上げます。 この例では、 concurrent.futures モジュールをインポートすることから始める必要があります。 次に、* load_url()という名前の関数が作成され、要求されたURLがロードされます。 次に、プール内の5つのスレッド数で *ProcessPoolExecutor が作成されます。 Process * PoolExecutor は、コンテキストマネージャーとして利用されています。 将来の結果を取得するには、 result()*メソッドを呼び出します。
出力
上記のPythonスクリプトは次の出力を生成します-
Executor.map()関数の使用
Pythonの* map()関数は、多くのタスクを実行するために広く使用されています。 そのようなタスクの1つは、特定の関数をiterables内のすべての要素に適用することです。 同様に、イテレータのすべての要素を関数にマップし、これらを独立したジョブとして *ProcessPoolExecutor に送信できます。 これを理解するには、次のPythonスクリプトの例を検討してください。
例
- Executor.map()関数を使用してスレッドプールを作成するときに使用したのと同じ例を検討します。 以下の例では、map関数を使用して、values配列のすべての値に square()*関数を適用しています。
出力
上記のPythonスクリプトは、次の出力を生成します
ProcessPoolExecutorとThreadPoolExecutorを使用する場合
executorクラス(ThreadPoolExecutorとProcessPoolExecutor)の両方について学習したので、どのエクゼキューターをいつ使用するかを知る必要があります。 CPUバウンドワークロードの場合はProcessPoolExecutorを選択し、I/Oバウンドワークロードの場合はThreadPoolExecutorを選択する必要があります。
例
出力
出力
上記の両方のプログラムの出力から、 ProcessPoolExecutor と ThreadPoolExecutor を使用しているときの実行時間の違いを確認できます。