-
[Python] GIL — 파이썬은 왜 멀티코어를 막아놓았을까IT 2026. 1. 23. 11:16
파이썬으로 어느 정도 개발을 하다 보면, 언젠가 반드시 이 질문을 만나게 됩니다.
“왜 파이썬은 멀티스레드를 써도 CPU를 하나만 쓰는 것 같지?”
그리고 곧이어 등장하는 단어가 바로 GIL(Global Interpreter Lock) 입니다. 이 글에서는 GIL을 단순히 ‘파이썬의 한계’로 설명하지 않고, 왜 이런 선택이 나왔는지, 그리고 우리가 어떻게 받아들이고 활용해야 하는지를 중심으로 풀어보려 합니다.
GIL이란 무엇인가
GIL은 말 그대로 전역 인터프리터 락입니다.
CPython 인터프리터는 내부적으로 한 시점에 하나의 스레드만이 바이트코드를 실행할 수 있도록 설계되어 있습니다. 이 제약을 강제하는 장치가 바로 GIL입니다.
즉,
- 멀티스레드를 만들 수는 있지만
- 동시에 파이썬 코드를 실행할 수는 없다
라는 구조입니다.
그럼 멀티스레드는 왜 있나?
이 지점에서 많은 사람들이 혼란을 느낍니다.
“어차피 동시에 실행 못 하는데, 스레드는 왜 존재하지?”
답은 I/O 작업에 있습니다.
- 네트워크 요청
- 파일 읽기
- 데이터베이스 대기
이런 작업들은 CPU를 쓰지 않고 대기 상태에 들어갑니다. 이때 GIL은 다른 스레드에게 넘어갈 수 있고, 결과적으로 멀티스레드는 I/O 중심 작업에서는 충분히 효과적입니다.
왜 이런 구조를 선택했을까
GIL은 우연히 생긴 것이 아닙니다. 매우 현실적인 선택의 결과입니다.
1. 메모리 모델을 단순하게 유지하기 위해
CPython의 객체는 참조 카운트(reference count) 방식으로 메모리를 관리합니다.
obj.refcount += 1 obj.refcount -= 1이 연산이 여러 스레드에서 동시에 일어나면 어떻게 될까요? 모든 객체 접근마다 락이 필요해집니다.
GIL은 이 복잡함을 통째로 제거합니다.
- 객체 접근은 안전해지고
- 인터프리터 구현은 단순해지며
- C 확장 모듈도 훨씬 작성하기 쉬워집니다
2. 성능은 생각보다 나쁘지 않았다
GIL은 직관적으로는 느릴 것 같지만, 실제로는 많은 경우 싱글 스레드 성능을 희생하지 않습니다.
- 락 경쟁이 없다
- 캐시 친화적이다
- 단일 스레드 코드가 매우 빠르다
이 때문에 “GIL을 없애면 무조건 빨라진다”는 생각은 사실과 거리가 있습니다.
GIL과 CPU-bound 작업
문제는 CPU 연산이 많은 작업입니다.
def heavy(): total = 0 for i in range(10**7): total += i return total이런 작업을 멀티스레드로 나눠도, 실제로는 한 스레드씩 번갈아 실행될 뿐입니다. 결과적으로 속도 향상은 거의 없습니다.
이 지점에서 파이썬 개발자들은 다른 선택지를 사용합니다.
파이썬에서의 현실적인 대응 전략
1. 멀티프로세싱
프로세스는 GIL을 공유하지 않습니다.
from multiprocessing import Process- 각 프로세스는 독립된 GIL을 가진다
- 실제 멀티코어 사용 가능
- 대신 IPC 비용이 발생
2. C 확장 / NumPy
많은 고성능 라이브러리는 GIL을 해제한 상태에서 C 코드로 연산을 수행합니다.
- NumPy
- Pandas 내부 연산
- 머신러닝 라이브러리
그래서 파이썬이 느리다는 인식과 달리, 실제 계산은 매우 빠른 경우가 많습니다.
3. 비동기 프로그래밍
앞서 이야기한 코루틴, 이벤트 루프는 GIL을 피하려는 시도라기보다, 대기 시간을 효율적으로 쓰기 위한 전략입니다.
- CPU를 나누는 것이 아니라
- 기다리는 시간을 숨긴다
GIL은 파이썬의 결함일까
이 질문에 대한 답은 간단하지 않습니다.
GIL은 분명 제약입니다. 하지만 동시에:
- 파이썬을 지금의 파이썬답게 만든 핵심 요소이기도 합니다
- 방대한 C 확장 생태계를 가능하게 했고
- 언어의 단순함과 안정성을 지켜왔습니다
마무리하며
GIL을 이해할 때 가장 중요한 관점은 이것입니다.
“파이썬은 병렬 계산 언어가 아니라, 생산성 중심 언어다”
그래서 파이썬은
- CPU-bound → 멀티프로세스, C 확장
- I/O-bound → 멀티스레드, 코루틴
이라는 전략을 자연스럽게 선택하게 됩니다.
GIL은 피해야 할 괴물이 아니라, 파이썬이라는 언어의 성격을 가장 잘 드러내는 장치라고 볼 수 있습니다.
'IT' 카테고리의 다른 글
[Python] 이벤트 루프는 어떻게 동작하는가 — Pseudo-code로 보는 Asyncio의 내부 (1) 2026.01.23 [Python] Async 핵심 개념 3부작 — 이벤트 루프, 동시성, 블로킹 (1) 2026.01.23 [Python] 서브루틴과 코루틴 — 흐름을 누가 쥐고 있는가 (1) 2026.01.23 [Python] abc 모듈과 추상 메서드 — 규칙을 코드로 표현하는 방법 (0) 2026.01.23 [Python] 커링(currying)을 이해한다는 것 (0) 2026.01.23