Python 3.2では、Concurrent Futuresが導入されました。これは、古いスレッド化モジュールとマルチプロセッシングモジュールの高度な組み合わせのようです。
これを古いマルチプロセッシングモジュールよりもCPUバウンドタスクに使用することの利点と欠点は何ですか?
この記事は、作業がはるかに簡単であることを示唆しています。
Python 3.2では、Concurrent Futuresが導入されました。これは、古いスレッド化モジュールとマルチプロセッシングモジュールの高度な組み合わせのようです。
これを古いマルチプロセッシングモジュールよりもCPUバウンドタスクに使用することの利点と欠点は何ですか?
この記事は、作業がはるかに簡単であることを示唆しています。
回答:
私はこれconcurrent.futures
以上「高度な」とは言いません。これは、基礎となる並列化の仕掛けとして複数のスレッドまたは複数のプロセスを使用するかどうかに関係なく、ほとんど同じように機能する単純なインターフェイスです。
つまり、「より単純なインターフェース」の事実上すべてのインスタンスと同様に、ほぼ同じトレードオフが関係します。学習曲線が浅くなります。これは、主に、学習できるものが非常に少ないためです。ただし、提供されるオプションが少ないため、最終的には、よりリッチなインターフェースではできない方法で不満を感じる可能性があります。
CPUにバインドされたタスクに関する限り、それはあまり意味がないため、あまり意味がありません。CPythonでのCPUにバインドされたタスクの場合、速度を上げるチャンスを得るには、複数のスレッドではなく複数のプロセスが必要です。ただし、速度向上の程度(ある場合)は、ハードウェア、OSの詳細、特に特定のタスクに必要なプロセス間通信の量によって異なります。内部では、すべてのプロセス間並列化の仕掛けは同じOSプリミティブに依存しています。これらを実現するために使用する高レベルAPIは、最終的な速度の主な要因ではありません。
編集:例
あなたが参照した記事に示されている最終的なコードは次のとおりですが、それを機能させるために必要なインポート文を追加しています。
from concurrent.futures import ProcessPoolExecutor
def pool_factorizer_map(nums, nprocs):
# Let the executor divide the work among processes by using 'map'.
with ProcessPoolExecutor(max_workers=nprocs) as executor:
return {num:factors for num, factors in
zip(nums,
executor.map(factorize_naive, nums))}
multiprocessing
代わりに使用することとまったく同じです:
import multiprocessing as mp
def mp_factorizer_map(nums, nprocs):
with mp.Pool(nprocs) as pool:
return {num:factors for num, factors in
zip(nums,
pool.map(factorize_naive, nums))}
multiprocessing.Pool
オブジェクトをコンテキストマネージャとして使用する機能は、Python 3.3で追加されました。
どちらが使いやすいですか?笑;-)それらは本質的に同じです。
違いの1つは、Pool
さまざまな方法をサポートしているため、学習曲線をかなり上に登るまでは、どれほど簡単かを理解できない可能性があることです。
繰り返しますが、これらすべての異なる方法は、長所と短所の両方です。状況によっては柔軟性が必要になる場合があるため、これらは強みです。「できればそれを行うには、たった1つの明確な方法が望ましい」という理由から、これらは弱点です。(可能であれば)のみに固執するプロジェクトconcurrent.futures
は、その最小限のAPIの使用方法に不必要な新奇性がないため、おそらく長期的には維持しやすくなります。
ProcessPoolExecutor
実際には、キャンセルを許可するインスタンスを返す()、発生した例外を確認する()、完了時に呼び出されるコールバックを動的に追加する()よりもPool
、実際には多くのオプションがあります。これらの機能は、によって返されるインスタンスでは使用できません。他の方法に起因してより多くのオプションを持っている/ 、、及びでによって露出複数の方法と、インスタンス。ProcessPoolExecutor.submit
Future
cancel
exception
add_done_callback
AsyncResult
Pool.apply_async
Pool
initializer
initargs
maxtasksperchild
context
Pool.__init__
Pool
Pool
ではなく、モジュールについてでした。 Pool
はの内容のごく一部でありmultiprocessing
、ドキュメントのかなり下にあるため、に存在していることを人々が理解するまでには時間がかかりますmultiprocessing
。この特定の回答はPool
、OPがリンクするすべての記事であり、それcf
は「操作がはるかに簡単」であるため、焦点を当てました。この記事で説明した内容は正しくありません。超えて、というcf
のはas_completed()
、非常に便利です。