백엔드/Python

[Python] Pool, ThreadPoolExecutor 비교

작은소행성☄️ 2025. 3. 10. 13:26
728x90

 

Python에서 Pool (multiprocessing)과 ThreadPoolExecutor (concurrent.futures)는 각각 멀티프로세싱멀티스레딩을 활용하는 방식이다. 

이 글에서는 두 방법의 차이점을 설명하고, 어떤 상황에서 어떤 방법을 선택해야 하는지 정리해 보았다.

 

multiprocessing.Pool

multiprocessing 모듈은 Python의 GIL(Global Interpreter Lock) 제한을 우회하여 병렬 처리를 가능하게 한다. 

Pool 클래스는 여러 개의 프로세스를 생성하여 태스크를 병렬 실행할 수 있도록 한다.

from multiprocessing import Pool

num_workers = 128
with Pool(processes=num_workers) as pool:
    results = pool.map(some_function, data_list)

 

특징

  • 멀티프로세싱 기반: 별도의 프로세스를 생성하여 GIL 영향을 받지 않음
  • CPU 집약적인 작업에 적합: 데이터 변환, 머신러닝 연산 등 연산이 많은 작업에 유리함
  • 메모리 사용량이 많을 수 있음: 프로세스 간 데이터 복사가 발생할 수 있음

 

ThreadPoolExecutor

concurrent.futures 모듈의 ThreadPoolExecutor는 Python의 스레드를 활용하여 병렬 처리를 수행한다.

from concurrent.futures import ThreadPoolExecutor

num_workers = 128
with ThreadPoolExecutor(max_workers=num_workers) as executor:
    results = list(executor.map(some_function, data_list))

 

특징

  • 멀티스레딩 기반: Python의 GIL 때문에 CPU 연산이 많은 작업에는 비효율적
  • I/O 바운드 작업에 적합: 네트워크 요청, 파일 I/O, 데이터베이스 조회 등에서 유리함
  • 메모리 사용이 적음: 같은 프로세스 내에서 스레드가 공유 메모리를 사용

 

비교

비교 항목 multiprocessing.Pool ThreadPoolExecutor
실행 방식 멀티프로세싱 (여러 프로세스 생성) 멀티스레딩 (여러 스레드 생성)
GIL 영향 없음 (각 프로세스가 독립적으로 실행) 있음 (스레드가 GIL 공유)
적합한 작업 CPU 연산이 많은 작업 I/O 작업 (DB, 파일 I/O, 네트워크 요청)
메모리 공유 프로세스 간 데이터 공유 어려움 같은 메모리 공간 공유
성능 프로세스 간 통신 비용이 큼 스레드 간 데이터 공유가 빠름

 

어떤 경우에 사용해야 할까?

상황 적합한 방식
CPU 바운드 작업 (대규모 연산, 머신 러닝, 이미지 처리) multiprocessing.Pool
I/O 바운드 작업 (네트워크 요청, DB 쿼리, 파일 입출력) ThreadPoolExecutor

 

  • CPU 연산이 많은 경우 → multiprocessing.Pool
  • 네트워크, 파일 처리 같은 I/O 작업, 메모리 사용 줄이고 싶을 때 → ThreadPoolExecutor

 

728x90
반응형