Pool.apply 、 Pool.apply_async 、 のユースケースの明確な例は見ていません。 Pool.map 私は主にPool.map
を使っています。他人の利点は何ですか?
Pythonの昔には、任意の引数で関数を呼び出すには、apply
を使用します。
apply(f,args,kwargs)
apply
はまだPython2.7には存在しますがPython3には存在せず、一般的にはもう使用されていません。今日、
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 __== '__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
とは異なり、結果は引数の順序に対応する順序で返されます。
apply
vs map
について:
pool.apply(f, args)
:f
はプールのワーカーのうちの1つでのみ実行されます。そのため、プール内の1つのプロセスでf(args)
が実行されます。
pool.map(f, iterable)
:このメソッドはイテラブルをいくつかのチャンクに分割し、それらを別々のタスクとしてプロセスプールに送ります。だからあなたはプール内のすべてのプロセスを利用する。