hhkb.dev

BLOG

2025-12-16 / 파이썬기초 · 04

멀티 스레드vs멀티 프로세스

1. 동시성 vs 병렬성

둘은 비슷해 보이지만 기준이 다르다. 먼저 이 차이를 분리해서 봐야 멀티 스레드와 멀티 프로세스를 제대로 고를 수 있다.

  • 동시성(Concurrency):
    • 논리적으로 동시에 처리되는 것처럼 보이게 만드는 개념이다.
    • 실제로는 작업 전환이 아주 빨라서 동시에 도는 느낌이 난다.
    • 한 명의 요리사가 칼질하다가, 끓는 동안 설거지를 하고, 다시 칼질하는 상황에 가깝다.
  • 병렬성(Parallelism):
    • 물리적으로 같은 시간에 실제로 함께 실행되는 개념이다.
    • 멀티 코어 CPU를 써서 진짜로 동시에 처리한다.
    • 요리사 두 명이 각각 다른 일을 나눠 하는 상황에 가깝다.

2. GIL(Global Interpreter Lock)

CPython에서는 GIL 때문에 스레드 선택이 단순하지 않다.

  • GIL이란:
    • Global Interpreter Lock의 약자다.
    • 한 순간에는 하나의 스레드만 파이썬 바이트코드를 실행하게 막는 잠금 장치다.
  • 왜 있는가:
    • 레퍼런스 카운팅 기반 메모리 관리를 단순하게 만들고, 기본적인 스레드 안전성을 확보하기 위해 도입됐다.
  • 결과:
    • 스레드를 많이 만들어도 CPU 연산 구간에서는 동시에 여러 스레드가 파이썬 코드를 실행하지 못한다.
    • 멀티 코어가 있어도 CPU Bound 작업에서는 기대만큼 병렬 처리가 나오지 않는다.

3. 상황별 사용

3.1. I/O Bound 작업 (입출력 중심) → Threading 사용

네트워크 통신, 파일 읽기·쓰기, DB 쿼리처럼 대기 시간이 긴 작업은 스레드가 잘 맞는다.

  • 특징: CPU가 계산하는 시간보다 응답을 기다리는 시간이 훨씬 길다.
  • 작동 원리:
    1. 스레드 A가 요청을 보낸 뒤 응답을 기다린다.
    2. 대기하는 동안 GIL을 놓는 구간이 생긴다.
    3. 그 사이 다른 스레드가 실행을 이어받아 다음 작업을 처리한다.

그래서 포트 스캐너나 크롤러처럼 I/O가 많은 작업에서는 스레딩이 꽤 효과적이다.

3.2. CPU Bound 작업 (연산 중심) → Multiprocessing 사용

암호 해독, 이미지 처리, 복잡한 수학 연산처럼 CPU를 계속 써야 하는 작업은 멀티프로세싱이 맞다.

  • 특징: 대기보다 연산 비중이 훨씬 크다.
  • 문제점: 스레드를 쓰면 GIL 경쟁 때문에 오버헤드만 늘고, 오히려 느려질 수 있다.
  • 해결책:
    • multiprocessing으로 프로세스를 여러 개 띄운다.
    • 각 프로세스는 별도 메모리 공간과 별도 인터프리터를 가진다.
    • 그래서 각자 자기 GIL을 쓰며 실제 병렬 처리에 가까워진다.

정리하면, CPU Bound 작업은 스레드보다 멀티프로세싱이 기본 선택이다.