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


답변:


424

옛날 파이썬에서 임의의 인수로 함수를 호출하려면 다음을 사용하십시오 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인수의 순서에 따라 결과가 반환됩니다.


11
Windows에 if __name__=="__main__"이전 apply_async_with_callback()에 있어야합니까 ?
jfs

3
고마워 map_async는 어떻습니까?
Phyo Arkar Lwin

38
multiprocessing / pool.py 내부를 살펴보면 다음Pool.map(func,iterable)같습니다 Pool.map_async(func,iterable).get(). 사이의 관계 그래서 Pool.map와는 Pool.map_async유사하다 Pool.applyPool.apply_async. async명령이 아닌 async블록 은 명령이 즉시 반환 됩니다. async명령은 콜백을 가지고있다.
unutbu

7
사용 사이의 결정 Pool.mapPool.apply사용시기 결정과 유사 map또는 apply파이썬한다. 작업에 맞는 도구 만 사용하면됩니다. asyncasync버전 과 비 버전 사이의 결정 은 전화가 현재 프로세스를 차단하도록하거나 콜백을 사용 하려는지에 달려 있습니다.
unutbu

6
@falsePockets : 예. 각 호출 apply_asyncApplyResult객체 를 반환 합니다. ApplyResultget메소드를 호출 하면 관련 함수의 반환 값이 반환되거나 mp.TimeoutError호출 시간이 초과되면 발생합니다. 따라서 ApplyResults를 순서 목록에 넣으면 해당 get메소드 를 호출 하면 결과가 동일한 순서로 반환됩니다. pool.map그러나이 상황에서 사용할 수 있습니다 .
unutbu

75

applyvs에 관해서 map:

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

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


4
iterable이 발전기 인 경우
RustyShackleford

흠 ... 좋은 질문입니다. 솔직히 말해서, 생성기와 함께 풀을 사용한 적이 없지만이 스레드가 도움이 될 수 있습니다. stackoverflow.com/questions/5318936/…
kakhkAtion

@kakhkAtion 적용과 관련하여 작업자 중 한 명만 기능을 실행하면 나머지 작업자는 무엇을합니까? 나머지 근로자가 작업을 수행하도록하려면 apply를 여러 번 호출해야합니까?
Moondra

3
진실. 작업자를 비동기식으로 점심 식사를하려면 pool.apply_async도 살펴보십시오. "결과가 준비 될 때까지 pool_apply가 차단되므로 apply_async ()가 병렬 작업을 수행하는 데 더 적합합니다"
kakhkAtion

1
4 개의 프로세스가 있지만 apply_async()8 번 호출하면 어떻게됩니까 ? 대기열로 자동 처리합니까?
Saravanabalagi Ramachandran

31

여기에서의 차이점을 표시하기 위해, 테이블 형식의 개요는 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에서 전체 설명서를 찾으십시오.


2
Pool.starmap () 님을 차단했습니다
Alan Evangelista
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.