파이썬의 병렬처리 (Parallelism)

파이썬에서 병렬처리란 여러 작업을 동시에 실행하여 전체 실행 시간을 단축시키는 기법입니다. 주로 멀티프로세싱(multiprocessing)과 멀티스레딩(multithreading)을 사용하며, CPU 바운드 작업에서는 멀티프로세싱을, I/O 바운드 작업에서는 멀티스레딩을 많이 사용합니다.

1. multiprocessing — 여러 프로세스를 사용하여 병렬 처리

from multiprocessing import Pool
import time

def square(x):
    time.sleep(1)
    return x * x

if __name__ == "__main__":
    nums = [1, 2, 3, 4, 5]
    with Pool(5) as p:  # 5개의 프로세스 사용
        results = p.map(square, nums)
    print(results)  # [1, 4, 9, 16, 25]
  • Pool 객체를 써서 여러 프로세스가 데이터를 나눠서 처리함
  • CPU를 100% 활용할 수 있다는 장점

2. threading — 여러 스레드로 I/O 병렬 처리

import threading
import time

def worker(num):
    print(f"Thread {num} start")
    time.sleep(2)
    print(f"Thread {num} done")

threads = []
for i in range(3):
    t = threading.Thread(target=worker, args=(i,))
    t.start()
    threads.append(t)

for t in threads:
    t.join()
  • 스레드는 GIL(Global Interpreter Lock)에 묶여있어서 CPU 바운드 작업은 속도가 잘 늘지 않음
  • 하지만 파일 읽기, 네트워크 요청 등 I/O 작업에서는 효과적

3. concurrent.futures — 고수준 API (멀티프로세스/멀티스레드 모두 지원)

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor

def square(x):
    return x * x

# ThreadPoolExecutor 예시 (I/O 바운드에 적합)
with ThreadPoolExecutor(max_workers=4) as executor:
    results = list(executor.map(square, [1, 2, 3, 4]))
    print(results)  # [1, 4, 9, 16]

# ProcessPoolExecutor 예시 (CPU 바운드에 적합)
with ProcessPoolExecutor(max_workers=4) as executor:
    results = list(executor.map(square, [1, 2, 3, 4]))
    print(results)
  • concurrent.futures는 병렬처리 코드를 더 쉽게 작성할 수 있는 표준 라이브러리

정리

  • CPU 바운드 — multiprocessing, ProcessPoolExecutor
  • I/O 바운드 — threading, ThreadPoolExecutor
  • 데이터 병렬·맵리듀스·대용량 처리 — Dask, Ray 같은 프레임워크