파이썬/기초 프로그래밍

파이썬 concurrent.futures를 이용한 병행 처리 간단 이해하기

Data Jun 2025. 9. 9. 14:21

파이썬에서 여러 작업을 동시에 실행하고 싶을 때 유용한 모듈이 **concurrent.futures**입니다. 이번 예제는 ThreadPoolExecutor를 사용해 여러 개의 합계를 동시에 계산하는 코드입니다.

 

1. 코드 구조

import time
from concurrent import futures

WORK_LIST = [10000, 100000, 1000000, 10000000]

def sum_generator(n):
    return sum(range(1, n+1))

def main():
    start_tm = time.time()

    # CPU-bound 작업 → ProcessPoolExecutor 사용
    with futures.ProcessPoolExecutor() as executor:
        result = executor.map(sum_generator, WORK_LIST)

    end_tm = time.time() - start_tm

    print("Result -> {} Time : {:.2f}s".format(list(result), end_tm))


if __name__ == '__main__':
    main()
  • ThreadPoolExecutor: 여러 개의 스레드를 풀(pool)로 만들어 작업을 분산 실행.
  • executor.map(func, iterable): map처럼 동작하지만, 여러 스레드에서 동시에 실행.
  • 결과 반환: list(result)를 호출하면 모든 작업의 결과가 순서대로 모임.

1️⃣ 실행 흐름

  • WORK_LIST의 각 숫자에 대해 sum_generator 실행.
  • ThreadPoolExecutor가 작업을 나눠 스레드에서 동시에 처리.
  • 모든 결과를 모아 최종 합계와 걸린 시간 출력.

 

간단한 실행 예시

Result -> [50005000, 5000000050000, 500000000500000, 50000000005000000] Time : 0.12s

큰 입력값(예: 천만)도 동시에 처리하기 때문에 순차 실행보다 훨씬 빠르게 끝납니다.

 

 

2️⃣  ThreadPoolExecutor vs ProcessPoolExecutor

 

ThreadPoolExecutor

  • 스레드 기반 동시성.
  • 동일한 프로세스 내에서 스레드를 여러 개 만들어 실행.
  • GIL(Global Interpreter Lock) 때문에 I/O 중심 작업에 유리.

ProcessPoolExecutor

  • 프로세스 기반 병렬성.
  • 여러 개의 파이썬 프로세스를 띄워서 CPU 코어를 활용.
  • 각 프로세스는 독립적인 메모리 공간을 가져서 GIL의 영향을 받지 않음.
  • 따라서 CPU 집약적 작업에 유리.

 

2. ASCII 다이어그램으로 보는 실행 흐름

1️⃣  ThreadPoolExecutor (스레드 기반)

[Main Process]
     |
     +--[Thread-1] sum_generator(10000)
     +--[Thread-2] sum_generator(100000)
     +--[Thread-3] sum_generator(1000000)
     +--[Thread-4] sum_generator(10000000)

 

하나의 프로세스 안에서 여러 스레드가 작업을 동시에 처리합니다.

 

2️⃣ ProcessPoolExecutor (프로세스 기반)

[Main Process]
     |
     +--[Process-1] sum_generator(10000)
     +--[Process-2] sum_generator(100000)
     +--[Process-3] sum_generator(1000000)
     +--[Process-4] sum_generator(10000000)

 

작업마다 별도의 프로세스가 실행되어, 여러 CPU 코어를 활용해 병렬 계산이 가능합니다.

 

3️⃣  실행 흐름 요약

  • ThreadPoolExecutor: 같은 프로세스 안에서 여러 스레드가 일을 나눠 처리 → I/O에 적합.
  • ProcessPoolExecutor: 여러 프로세스를 띄워 병렬 실행 → CPU 연산에 적합.

 

 

정리하면

  • concurrent.futures는 파이썬에서 병행성을 쉽게 구현할 수 있는 고수준 API.
  • ThreadPoolExecutor는 I/O 중심 작업에, ProcessPoolExecutor는 CPU 중심 작업에 적합.
  • .map()을 활용하면 리스트나 반복 가능한 객체를 병렬로 처리할 수 있어 코드가 간결해짐.

이 예제는 동시에 여러 합계 계산을 수행해 시간을 단축하는 기본 패턴을 보여줍니다.