2020.03.16 Multiprocessing의 map_async, apply등 나머지

Multiprocessing에서 map 함수의 불편한 점은 2개 이상의 인자를 취하는 함수를 사용할 수 없다는 것이다.

예를 들어 pool.map(func, [(10, 20)])을 하면 func의 첫번째 인자로 10, 두번째 인자로 20이 들어가기를 기대하지만 막상 실행해보면 그냥 첫번째 인자에 (10, 20) 튜플이 들어가게 된다.

이 땐 multi-argument를 accept 하는 함수로 starmap을 사용할 수 있다.

map_async

callback과 error_callback을 인자로 받을 수 있다.
Non-block 방식이기 때문에 프로세스에게 일감을 부여하고 바로 다시 메인 쓰레드로 제어권이 돌아온다.
제어권이 돌아오고 다른 프로세스들은 job을 열심히 돌릴텐데, 이 때 job의 결과물이 모두 반환되면 실행할 callback을 정의할 수 있다.
각 프로세스별로 실행한 함수의 return값을 모두 모아서 callback의 인자로 넘겨준다.
따라서 callback을 정의하여 어디에 notify를 해주던가, 알려주던가 하는 방법이 있다.
완료 되었을 때 callback을 넘겨줄 수 있기 떄문에 후처리를 해줄 수 있다.
이를 확인할 수 있는 함수는 get, wait, ready, successful

    def callback(res):
        print(res)

    pool = multiprocessing.Pool()                       # 현재 PC의 CPU 코어가 12개이다.
    a = pool.map_async(calc, range(21, 26), callback=callback)
    print(a.ready())
    print('Block이 아니라고 하는데 위에서 pool.join()함수가 호출되면 본 프린트 문은 프로세스들의 작업이 모두 끝나야 콘솔에 찍힌다.')
    import time
    for i in range(10):
        print(i)
        time.sleep(0.5)
        print(a.ready())


apply

map과 apply는 매우 비슷하다.

다른 점이 있다면
    1) map은 인자로 (함수, iterable)을 받아서 이를 process들에게 모두 분배하지만 apply는 함수와 인자를 하나의 프로세스에게만 전달한다는 것이다.
    2) map, map_async는 프로세스가 실행하는 순서가 보장되는데에 반해 (제공된 인자의 순서), apply는 프로세스 실행 순서가 보장되지 않는다는 것이다.
    따라서 map을 사용할 때 pool.map(func, [1,2,3]) 과 같은 코드가 있고 이를 apply로 구현한다면
    pool.apply(func, 1)
    pool.apply(func, 2)
    pool.apply(func, 3)
    이렇게 세 번 해야한다.

이를 활용한 apply 함수의 장점은 map은 하나의 함수만을 여러 프로세스에 전달할 수 있는 것에 반해 apply는 다른 함수들을 다른 프로세스들에게 던져줄 수 있다는 것이다.

댓글

이 블로그의 인기 게시물

로컬 Tomcat 서버 실행속도 개선

2019.05.23 - SQLAlchemy 의 객체 상태 관리 (expire, refresh, flush, commit) 에 관한 이해

2020.02.17 Python의 multiprocessing 중 Pool.map(), chunksize에 관한 내용