multiprocessing.Pool: apply、apply_async、map はいつ使用すればよいですか? 質問する

multiprocessing.Pool: apply、apply_async、map はいつ使用すればよいですか? 質問する

明確な使用例を見たことがありませんプール.適用プール.apply_asyncそしてプールマップを主に使用していますPool.mapが、他の利点は何ですか?

ベストアンサー1

Python の昔では、任意の引数を持つ関数を呼び出すには、次のようにしていましたapply

apply(f,args,kwargs)

applyPython3には存在しませんが、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.applyPool.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.applyPool.mapは完全な結果が返されるまでブロックします。

ワーカー プロセスのプールで多数の関数呼び出しを非同期的に実行する場合は、 を使用しますPool.apply_async。結果の順序は、 の呼び出し順序と同じになるとは限りませんPool.apply_async

また、 を使用してさまざまな関数を呼び出すことができることにも注意してくださいPool.apply_async(すべての呼び出しで同じ関数を使用する必要はありません)。

対照的に、Pool.mapは同じ関数を複数の引数に適用します。ただし、 とは異なりPool.apply_async、結果は引数の順序に対応する順序で返されます。

おすすめ記事