Pool.apply、Pool.apply_async、およびPool.mapのユースケースを示す明確な例は見ていません。主に使用していPool.map
ます。他の人の利点は何ですか?
Pool.apply、Pool.apply_async、およびPool.mapのユースケースを示す明確な例は見ていません。主に使用していPool.map
ます。他の人の利点は何ですか?
回答:
Pythonの昔、任意の引数で関数を呼び出すには、次のようにしますapply
。
apply(f,args,kwargs)
apply
Python3にはありませんが、Python2.7にはまだ存在し、通常は使用されていません。今日、
f(*args,**kwargs)
推奨されます。multiprocessing.Pool
モジュールは、同様のインタフェースを提供しようとします。
Pool.apply
Python apply
に似ていますが、関数呼び出しが別のプロセスで実行される点が異なります。Pool.apply
関数が完了するまでブロックします。
Pool.apply_async
また、Pythonの組み込みと似apply
ていますが、呼び出しが結果を待つのではなく、すぐに戻る点が異なります。AsyncResult
オブジェクトが返されます。そのget()
メソッドを呼び出して、関数呼び出しの結果を取得します。get()
メソッドのブロック機能が完了するまで。したがって、pool.apply(func, args, kwargs)
と同等pool.apply_async(func, args, kwargs).get()
です。
とは対照的にPool.apply
、Pool.apply_async
メソッドにはコールバックもあり、コールバックが指定されている場合は、関数が完了したときに呼び出されます。これはを呼び出す代わりに使用できますget()
。
例えば:
import multiprocessing as mp
import time
def foo_pool(x):
time.sleep(2)
return x*x
result_list = []
def log_result(result):
# This is called whenever foo_pool(i) returns a result.
# result_list is modified only by the main process, not the pool workers.
result_list.append(result)
def apply_async_with_callback():
pool = mp.Pool()
for i in range(10):
pool.apply_async(foo_pool, args = (i, ), callback = log_result)
pool.close()
pool.join()
print(result_list)
if __name__ == '__main__':
apply_async_with_callback()
次のような結果が得られる場合があります
[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]
とは異なりpool.map
、結果の順序はpool.apply_async
呼び出しが行われた順序と一致しない場合があります。
したがって、別のプロセスで関数を実行する必要があるが、その関数が戻るまで現在のプロセスをブロックする場合は、を使用しますPool.apply
。のようにPool.apply
、Pool.map
完全な結果が返されるまでブロックします。
ワーカープロセスのプールで多くの関数呼び出しを非同期に実行する場合は、を使用しますPool.apply_async
。オーダーの結果のはへの呼び出しの順序と同じであることが保証されていませんPool.apply_async
。
複数の異なる関数を呼び出すことができることにも注意してくださいPool.apply_async
(すべての呼び出しで同じ関数を使用する必要はありません)。
対照的にPool.map
、同じ関数を多くの引数に適用します。ただし、とは異なりPool.apply_async
、結果は引数の順序に対応する順序で返されます。
Pool.map(func,iterable)
と同等であることがわかりますPool.map_async(func,iterable).get()
。関係はそうPool.map
とPool.map_async
の場合と同様であるPool.apply
とPool.apply_async
。async
非ながらコマンドは、すぐに返すasync
コマンドをブロックします。async
コマンドは、コールバックを持っています。
Pool.map
とPool.apply
するときに使用する決定に類似しているmap
か、apply
Pythonで。仕事に合ったツールを使用するだけです。使用の間の決定async
および非async
バージョンにすると、呼び出しは現在のプロセスをブロックする場合、および/またはあなたがコールバックを使用する場合に依存します。
apply_async
返されApplyResult
ます。そのApplyResult
のget
メソッドを呼び出すと、関連付けられた関数の戻り値が返されます(またはmp.TimeoutError
呼び出しがタイムアウトになると発生します)。したがって、ApplyResult
sを順序付きリストに入れると、それらのget
メソッドを呼び出すと、同じ順序で結果が返されます。pool.map
ただし、この状況で使用できます。
apply
対についてmap
:
pool.apply(f, args)
:f
プールのワーカーの1つでのみ実行されます。したがって、プール内のプロセスの1つが実行されますf(args)
。
pool.map(f, iterable)
:このメソッドは、イテラブルをいくつかのチャンクに分割し、個別のタスクとしてプロセスプールに送信します。したがって、プール内のすべてのプロセスを利用できます。
apply_async()
8回呼び出した場合はどうなりますか?キューで自動的に処理されますか?
ここでの違いを示すためにテーブル形式の概要がありPool.apply
、Pool.apply_async
、Pool.map
とPool.map_async
。いずれかを選択するときは、複数引数、同時実行性、ブロック化、および順序付けを考慮する必要があります。
| Multi-args Concurrence Blocking Ordered-results
---------------------------------------------------------------------
Pool.map | no yes yes yes
Pool.map_async | no yes no yes
Pool.apply | yes no yes no
Pool.apply_async | yes yes no no
Pool.starmap | yes yes yes yes
Pool.starmap_async| yes yes no no
Pool.imap
およびPool.imap_async
– mapおよびmap_asyncのレイジーバージョン。
Pool.starmap
メソッドは、複数の引数を受け入れる以外はmapメソッドとよく似ています。
Async
メソッドはすべてのプロセスを一度に送信し、完了したら結果を取得します。getメソッドを使用して結果を取得します。
Pool.map
(またはPool.apply
)メソッドは、Pythonの組み込みマップ(または適用)と非常によく似ています。すべてのプロセスが完了して結果が返されるまで、メインプロセスをブロックします。
一度にジョブのリストが呼び出されます
results = pool.map(func, [1, 2, 3])
1つのジョブに対してのみ呼び出すことができます
for x, y in [[1, 1], [2, 2]]:
results.append(pool.apply(func, (x, y)))
def collect_result(result):
results.append(result)
一度にジョブのリストが呼び出されます
pool.map_async(func, jobs, callback=collect_result)
1つのジョブに対してのみ呼び出すことができ、バックグラウンドで並列にジョブを実行します
for x, y in [[1, 1], [2, 2]]:
pool.apply_async(worker, (x, y), callback=collect_result)
pool.map
複数の引数をサポートするバリアントです
pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
反復可能な反復可能オブジェクトを反復処理し、unterableをアンパックしてfuncを呼び出すstarmap()とmap_async()の組み合わせ。結果オブジェクトを返します。
pool.starmap_async(calculate_worker, [(1, 1), (2, 1), (3, 1)], callback=collect_result)
ここで完全なドキュメントを検索:https : //docs.python.org/3/library/multiprocessing.html
if __name__=="__main__"
前apply_async_with_callback()
にあるべきですか?