본문 바로가기
Backend2026년 5월 11일5분 읽기

Python 3.13 No-GIL — 진짜 멀티스레드, 어디서 빠르고 어디서 망가지나

YS
김영삼
조회 1182
Python 3.13 No-GIL — 진짜 멀티스레드, 어디서 빠르고 어디서 망가지나

핵심 요약

Python 3.13의 free-threaded(no-GIL) 빌드가 PEP 703에 따라 실험적이지만 안정 단계로 진입. CPU 바운드 워크로드에서 4~6배 가속이 현실이 됐다. 단, C 익스텐션 호환과 GIL 의존 코드 두 가지 함정.

1. 어떻게 켜나

# 빌드 시 옵션
./configure --disable-gil
make

# Docker 이미지
FROM python:3.13t-bookworm   # 't' suffix = threaded build

# 실행 시 환경 변수로 동작 확인
PYTHON_GIL=0 python script.py

2. 실측 — 다양한 워크로드

8코어 c7i.2xlarge에서 측정.

워크로드3.13 (GIL)3.13t가속
NumPy 행렬곱 8병렬3.4s3.4s1.0x (이미 GIL 해제)
순수 Python 소수 판정 8병렬14.6s2.4s6.1x
JSON 파싱 (orjson)1.2s1.1s1.1x
이미지 리사이즈 (Pillow)5.8s1.5s3.9x
asyncio HTTP fetch 10002.1s2.0s1.0x (I/O 바운드)
웹 서버 (FastAPI)2,200 RPS2,280 RPS1.04x

3. 어디서 빠른가

  • 순수 파이썬 CPU 작업: 가장 큰 가속
  • GIL을 안 놓는 C 확장: 여기서도 가속
  • 스레드 풀 활용 기존 코드: 코드 변경 없이 가속

4. 어디서 별 차이 없는가

  • NumPy·PyTorch 같은 이미 GIL 해제하는 라이브러리
  • I/O 바운드 (asyncio·aiohttp가 이미 단일 스레드에서 동시성)
  • 외부 프로세스 호출 위주

5. 깨지는 케이스

① 일부 C 익스텐션

모든 C 확장이 GIL 가정. 호환 표시(Py_mod_gil = Py_MOD_GIL_NOT_USED)가 없으면 free-threaded 빌드에서 GIL 임시 켜짐 → 가속 효과 없음.

2026-05 기준 호환 라이브러리: NumPy, Pillow, lxml, cryptography, psycopg2, ujson, ... (다수). 비호환 잔존: 옛 ML 라이브러리 일부.

② 글로벌 가변 상태

GIL이 있던 시절 "어쨌든 atomic"이었던 코드가 깨짐.

counter = 0
def worker():
    global counter
    for _ in range(10_000):
        counter += 1   # NOT atomic anymore!

해결: threading.Lock 또는 collections.Counter 같은 thread-safe 자료구조.

③ dict / list 동시 수정

GIL 덕에 단일 연산은 안전했지만 free-threaded에선 보장 없음. 명시적 락 필요.

6. 검사 도구

# pytest 플러그인
pip install pytest-freethreaded
pytest --freethreaded

# 데이터 레이스 탐지
PYTHONTHREADSANITIZER=1 python script.py

7. 실무 도입 결정

상황권장
이미지·동영상 처리 배치도입
ML 추론 서비스도입 검토 (라이브러리 확인)
웹 API (DB+CPU 가벼움)이득 적음, 보류 가능
레거시 큰 시스템3.13 일반 빌드 먼저, free-threaded는 나중

8. 마이그레이션 단계

  1. 3.12 → 3.13 (GIL 빌드)에서 안정화
  2. 의존성 free-threaded 호환 확인 (pip download의 wheel 태그 t)
  3. 스테이징에 3.13t 배포, 부하 테스트
  4. 락 누락 코드 발견 — pytest-freethreaded로
  5. 10% 카나리

9. 흔한 함정

  • "GIL 없으니 무조건 빠르다": I/O 바운드는 차이 없음
  • multiprocessing 그대로 둬도 됨: 동의. 하지만 threading이 더 가벼움
  • logger 호환: 표준 logging은 OK, 자체 logger는 락 확인
  • SQLAlchemy connection pool: pool 객체 자체는 thread-safe, 세션은 스레드별

10. 향후

3.14에서 free-threaded가 default 후보. 3.13t는 그 전 검증판. 라이브러리 측 호환 표시가 늘어나고 있어 매월 상황 변화.

참고

  • peps.python.org/pep-0703
  • py-free-threading.github.io — 호환 추적

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록