[python] 수영장 : apply, apply_async 또는 map을 언제 사용합니까?

Pool.apply , Pool.apply_async유스 케이스에 대한 명확한 예를 보지 못했습니다. Pool.map에 못했습니다 . 나는 주로 사용하고 있습니다 Pool.map; 다른 사람들의 장점은 무엇입니까?



답변

옛날 파이썬에서 임의의 인수로 함수를 호출하려면 다음을 사용하십시오 apply.

apply(f,args,kwargs)

applyPython3에는 없지만 Python2.7에는 여전히 존재하며 일반적으로 더 이상 사용되지 않습니다. 요즘,

f(*args,**kwargs)

선호됩니다. multiprocessing.Pool모듈은 유사한 인터페이스를 제공하려고합니다.

Pool.applyapply함수 호출이 별도의 프로세스에서 수행된다는 점을 제외하고 는 Python과 같습니다 . Pool.apply기능이 완료 될 때까지 차단합니다.

Pool.apply_async또한 apply결과를 기다리지 않고 호출이 즉시 반환된다는 점을 제외하고는 Python의 내장 기능과 같습니다 . 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인수의 순서에 따라 결과가 반환됩니다.


답변

applyvs에 관해서 map:

pool.apply(f, args): f풀의 작업자 중 하나에서만 실행됩니다. 따라서 풀의 프로세스 중 하나가 실행 f(args)됩니다.

pool.map(f, iterable):이 메소드는 iterable을 여러 청크로 분할하여 별도의 태스크로 프로세스 풀에 제출합니다. 따라서 풀의 모든 프로세스를 활용하십시오.


답변

여기에서의 차이점을 표시하기 위해, 테이블 형식의 개요는 Pool.apply, Pool.apply_async, Pool.mapPool.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.imapPool.imap_async-지도 및 map_async의 lazier 버전.

  • Pool.starmap 여러 인수를 허용하는 것 외에도 map 메서드와 매우 유사합니다.

  • Async메소드는 모든 프로세스를 한 번에 제출하고 완료되면 결과를 검색합니다. get 메소드를 사용하여 결과를 얻으십시오.

  • Pool.map(또는 Pool.apply) 메소드는 Python 내장 맵 (또는 적용)과 매우 유사합니다. 모든 프로세스가 완료되고 결과를 반환 할 때까지 기본 프로세스를 차단합니다.

예 :

지도

한 번에 작업 목록을 요구합니다

results = pool.map(func, [1, 2, 3])

대다

하나의 작업에 대해서만 호출 가능

for x, y in [[1, 1], [2, 2]]:
    results.append(pool.apply(func, (x, y)))

def collect_result(result):
    results.append(result)

map_async

한 번에 작업 목록을 요구합니다

pool.map_async(func, jobs, callback=collect_result)

apply_async

하나의 작업에 대해서만 호출 할 수 있으며 백그라운드에서 작업을 병렬로 실행

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)])

starmap_async

iterable을 반복하고 iterable을 압축 해제하여 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에서 전체 설명서를 찾으십시오.


답변