Python에서 글로벌 인터프리터 락(GIL) 은 동시성을 없애서 충돌이 없도록 하여, 쉽게 코딩할 수 있었지만, 그만큼 성능적으로 특히 멀티 코어에서 약점을 보였다. 하여 Python 3.12버전부터 GIL 없이 실행하는 방법은 주로 PEP 703에서 제안된 여러 기술을 통해 가능하게 되었는데, GIL은 CPython에서 여러 스레드가 동시에 Python 코드를 실행하는 것을 방지하는 메커니즘으로, 멀티코어 CPU를 효율적으로 활용하지 못하던 부분이 어떻게 가능하게 된 것일까? 관련하여 알아보도록 하자.
GIL 제거를 위한 주요 기술
멀티스레드에서 가장 큰 문제는 바로 변수 접근이라고 할 수 있다. 따라서 이를 Python에서는 객체가 참조되는지를 카운트하는 방식을 채택했다고 보면된다. 즉 삭제해도 되는 변수인지를 확인하는 참조 카운트를 도입하므로써, 참조가 있다면 유지하는 방식을 채택했다고 보면 된다. 그리고 특정 값은 참조가 아닌 해제하지 않고 유지하도록 한 부분들이 멀티 스레드를 진행할 때, 보다 안정성을 보장한 방법이라고 보면 된다.
편향 참조 카운팅 (Biased Reference Counting):
객체의 소유자 스레드에서만 참조 카운트를 증가/감소시켜 경합을 줄이고 처리를 빠르게 하는 기술이다. 다른 스레드에서 접근할 경우 추가적인 처리가 필요하게 된다.
지연 참조 카운팅 (Deferred Reference Counting):
참조 카운트 갱신을 즉시 수행하는 대신, 일정 시간 동안 참조가 변경되지 않으면 한꺼번에 갱신하는 방식을 채택한다. 이를 통해 오버헤드를 줄이고 성능을 향상시킨다.
참조 카운팅 불멸화 (Immortalization):
특정 객체들을 해제되지 않도록 설정하여 참조 카운트 관리를 피합니다. 예를 들어, True, False, None, 작은 정수, 빈 문자열 등이 이에 해당합니다.
GIL 없이 스레드를 실행하는 방법은 threading 라이브러리를 사용하면 가능하다.
import threading
def thread_function():
print("스레드에서 실행 중")
# GIL 없이 실행하는 예제 (가상 사용법)
thread = threading.Thread(target=thread_function)
thread.start()
thread.join()
마치며
아무래도 메모리 누수 문제는 지속적으로 업데이트하며 개선해야할 과제로 보인다.
'Python' 카테고리의 다른 글
BERT 모델을 이용해서 이상 문장 학습 및 탐지하기 (0) | 2025.04.16 |
---|---|
Python - 내장 변수 관리 locals() (0) | 2025.04.09 |
FastAPI - Docs, Redoc 비활성화 하기 (0) | 2025.03.28 |
Python - (pymysql.err.OperationalError) (1241, 'Operand should contain 1 column(s)') INSERT (0) | 2025.01.13 |
Python - uv 패키지, 프로젝트 관리자 설치 및 사용법 (0) | 2025.01.08 |