핵심 요약
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.4s | 3.4s | 1.0x (이미 GIL 해제) |
| 순수 Python 소수 판정 8병렬 | 14.6s | 2.4s | 6.1x |
| JSON 파싱 (orjson) | 1.2s | 1.1s | 1.1x |
| 이미지 리사이즈 (Pillow) | 5.8s | 1.5s | 3.9x |
| asyncio HTTP fetch 1000 | 2.1s | 2.0s | 1.0x (I/O 바운드) |
| 웹 서버 (FastAPI) | 2,200 RPS | 2,280 RPS | 1.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. 마이그레이션 단계
- 3.12 → 3.13 (GIL 빌드)에서 안정화
- 의존성 free-threaded 호환 확인 (
pip download의 wheel 태그 t) - 스테이징에 3.13t 배포, 부하 테스트
- 락 누락 코드 발견 — pytest-freethreaded로
- 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