1. ホーム
  2. python

[解決済み] マルチプロセシング・プール apply、apply_async、mapのどれを使うか?

2022-03-16 17:36:09

質問

のユースケースで明確な例を見たことがありません。 Pool.apply , Pool.apply_async プール.マップ . 私は主に 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 その結果は、引数の順序に対応する順序で返されます。