풀 : map_async와 imap의 차이점은 무엇입니까?


184

파이썬의 사용 방법을 배우려고 노력하고있어 multiprocessing패키지를,하지만 난 사이의 차이를 이해하지 않습니다 map_asyncimap. 나는 눈치 그 모두 map_asyncimap비동기 적으로 실행됩니다. 그렇다면 언제 다른 것을 사용해야합니까? 그리고 내가 반환 한 결과를 어떻게 검색해야 map_async합니까?

이런 식으로 사용해야합니까?

def test():
    result = pool.map_async()
    pool.close()
    pool.join()
    return result.get()

result=test()
for i in result:
    print i

답변:


492

imap/ imap_unorderedmap/ 사이에는 두 가지 주요 차이점이 있습니다 map_async.

  1. 그들이 당신이 그들에게 전달하는 iterable을 소비하는 방식.
  2. 그들이 당신에게 결과를 돌려주는 방법.

mapiterable을 목록으로 변환하고 (이미 목록이 아니라고 가정)이를 청크로 나누고 해당 청크를의 작업자 프로세스로 전송하여 iterable을 사용합니다 Pool. iterable을 청크로 나누면 프로세스마다 iterable의 각 항목을 한 번에 한 항목 씩 전달하는 것보다 낫습니다 (특히 iterable이 큰 경우). 그러나 전체 목록을 메모리에 보관해야하기 때문에 이터 러블을 목록으로 변환하여 청크를 만들려면 메모리 비용이 매우 높아질 수 있습니다.

imap반복 가능한 것을 목록으로 바꾸거나 덩어리로 나누지 않습니다 (기본적으로). 한 번에 반복 가능한 한 요소를 반복하여 각 요소를 작업자 프로세스로 보냅니다. 이것은 전체 iterable을리스트로 변환 할 때의 메모리 히트를 가져 오지 않지만, 청킹 (chunking)이 없기 때문에 큰 iterable의 경우 성능이 느려진다는 것을 의미합니다. chunksize그러나 기본값 1보다 큰 인수 를 전달하면이를 완화 할 수 있습니다 .

사이의 주요 차이점은 imap/ imap_unorderedmap/ map_async와 있다는 것입니다 imap/ imap_unordered당신이 곧 오히려 완료 될 그들 모두를 기다리는 것보다, 그들이있는 거 준비 등으로 노동자로부터 결과를 수신 시작할 수 있습니다. 와 map_asyncAsyncResult즉시 반환하지만, 그들 모두가 처리 될 때까지 당신이 실제로하는이 같은 목록을 반환 점, 그 객체의 결과를 검색 할 수 없습니다 map않습니다 ( map실제로 내부적으로 구현됩니다 map_async(...).get()). 부분적인 결과를 얻을 수있는 방법은 없습니다. 당신은 전체 결과를 얻거나 아무것도 없습니다.

imap그리고 imap_unordered모두 반환 즉시 반복 가능 객체. 를 사용 imap하면 입력 iterable의 순서를 유지하면서 준비가 완료되는 즉시 iterable에서 결과가 산출됩니다. 를 사용하면 imap_unordered반복 가능한 입력 순서에 관계없이 준비가 완료되는 즉시 결과가 산출됩니다. 따라서 이것이 있다고 가정하십시오.

import multiprocessing
import time

def func(x):
    time.sleep(x)
    return x + 2

if __name__ == "__main__":    
    p = multiprocessing.Pool()
    start = time.time()
    for x in p.imap(func, [1,5,3]):
        print("{} (Time elapsed: {}s)".format(x, int(time.time() - start)))

출력됩니다 :

3 (Time elapsed: 1s)
7 (Time elapsed: 5s)
5 (Time elapsed: 5s)

p.imap_unordered대신에 사용 p.imap하면 다음이 표시됩니다.

3 (Time elapsed: 1s)
5 (Time elapsed: 3s)
7 (Time elapsed: 5s)

당신이 사용하는 경우 p.map또는 p.map_async().get(), 당신은 볼 수 있습니다 :

3 (Time elapsed: 5s)
7 (Time elapsed: 5s)
5 (Time elapsed: 5s)

따라서 imap/ imap_unorderedover 를 사용하는 주요 이유 map_async는 다음과 같습니다.

  1. iterable은 목록으로 변환하면 너무 많은 메모리가 부족하거나 사용됩니다.
  2. 모든 결과 가 완료 되기 전에 결과 처리를 시작하려고합니다 .

1
apply 및 apply_async는 어떻습니까?
Harsh Daftary 2016 년

10
@HarshDaftary apply는 단일 작업을 작업자 프로세스로 보낸 다음 완료 될 때까지 차단합니다. apply_async단일 작업을 작업 프로세스로 보낸 다음 AsyncResult작업을 완료하고 결과를 검색하기 위해 대기하는 데 사용할 수 있는 개체 를 즉시 반환합니다 . apply단순히 호출하여 구현됩니다apply_async(...).get()
단오

51
그것은 기존의 둔한Pool 것이 아니라 공식 문서 에 있어야하는 종류의 설명입니다 .

@ dano 백그라운드에서 함수를 실행하고 싶지만 리소스 제한이 있으며 원하는 횟수만큼 함수를 실행할 수 없으며 함수의 추가 실행을 대기열에 넣고 싶습니다. 내가 어떻게 해야하는지에 대한 아이디어가 있습니까? 여기에 내 질문이 있습니다 . 내 질문을 살펴보고 어떻게 해야하는지에 대한 힌트 (또는 더 나은 대답)를 줄 수 있습니까?
Amir

1
@BallpointBen 완료되면 다음 작업으로 넘어갑니다. 주문은 상위 프로세스에서 다시 처리됩니다.
dano
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.