python

Python multiprocessing 으로 병렬처리

Like_Me 2021. 10. 31. 15:49

CPU를 사용해서 python을 처리하려다 보면 병렬 처리가 간절한 경우들이 생긴다. 이때 사용할 수 있는 간단한 방법이 python에 내장된 multiprocessing 라이브러리다. 사용법도 간단하고 직관적이라 바로 적용하기 간편하다는 장점이 있다.

multiprocessing 관련 가이드를 보면 오히려 글이 너무 길고 사용 방법이 복잡해 보여서 거부감이 들기 쉽다. 이 글에서는 가장 간단하게 적용할 수 있는 방법을 코드와 함께 남겨 놓는다.

우선 코드를 먼저 보면 다음과 같다.

from multiprocessing import Pool, cpu_count
import psutil


def _check_usage_of_cpu_and_memory():

    memory_usage = psutil.virtual_memory().percent
    available_memory = psutil.virtual_memory().available * 100 / \
        psutil.virtual_memory().total
    cpu_usage = psutil.cpu_percent()

    print(f"cpu usage: {cpu_usage}")
    print(f"memory usage: {memory_usage}")
    print(f"available_memory: {available_memory}")


def f(x):
    for _ in range(10000):
        x += 1
    _check_usage_of_cpu_and_memory()
    return x


cpu_num = cpu_count()

if __name__ == '__main__':
    print(f"cpu 개수 : {cpu_num}")
    with Pool(processes=cpu_num) as p:
        print(p.map(f, range(100)))

multiprocessing 라이브러리에서 Pool과 cpu_count를 import 했다. Pool은 병렬 처리하도록 도와주는 함수이며 cpu_count는 컴퓨터에 내장된 cpu (thread) 개수를 보여준다. 여기서는 간단히 10000번 동안 +1을 해주어 return 해주는 f(x)라는 함수를 만들어 분산 처리하는 예시를 들었다. pool.map을 사용하여 함수 f(x)에 0~99 (range(100)) 를 넣어 return값을 받는 과정을 병렬로 처리하였다. 1 process라면 100번 for문을 돌아야겠지만 여기서는 병렬 처리가 되어 훨씬 빠르게 종료된다.

Pool 객체를 사용할 때 processes 개수에 cpu_count를 이용해 받은 숫자를 넘겨줬는데 반드시 그럴 필요는 없다. 함수를 처리할 때 cpu 사용량을 체크해보고 여유가 많이 남는다면 더 크게 줄 수도 있다. 이는 직접 돌려 보며 확인을 하면 되는데 작업 관리자를 통해 볼 수도 있지만 python을 통해서도 볼 수 있다. 그걸 위해 psutil 라이브러리를 import 하였고 _check_usage_of_cpu_and_memory 함수에서 사용하였다. 변수명과 print 문을 보고 충분히 이해할 수 있을 것이라 생각한다.

이런 식으로 간단히 multiprocessing 처리를 하는 것을 알아 보았다. 처음부터 복잡한 글을 보며 익히는 것보다 기본에서 살을 붙여가며 학습하는 것이 좋다고 생각한다. 이제 기본을 파악했다면 자세한 가이드를 참고해보아도 좋을 것 같다.