GIL의 기본 역할과 참조 카운팅 보호
GIL(Global Interpreter Lock)은 CPython 인터프리터가 보유해야 하는 상호배제 락으로, 파이썬 객체 접근 시 필수입니다. GIL이 없다면 동시에 동일 객체의 참조 카운트를 증가시킬 때 경쟁 조건이 발생하여 카운트가 한 번만 증가될 수 있습니다. CPython의 참조 카운팅 메모리 관리 방식은 스레드에 안전하지 않기 때문에 GIL이 존재합니다.
스레드 스케줄링과 바이트코드 실행 모델
인터프리터는 스레드 간 동시성을 에뮬레이트하기 위해 바이트코드 명령 사이에서 정기적으로 스레드 전환을 시도합니다(sys.setswitchinterval()로 제어 가능, 기본값 5ms). 스레드가 GIL을 획득하면 할당된 간격 내 바이트코드를 실행하고, 시간 초과 또는 I/O 연산 진입 시 GIL을 해제하여 다른 스레드가 획득 가능하게 합니다.
I/O 연산과 락 해제 패턴
파일 읽기/쓰기 같은 블로킹 I/O 연산 수행 시 GIL이 자동으로 해제됩니다. 이를 통해 한 스레드가 외부 시스템 호출 대기 중일 때 다른 스레드가 파이썬 코드를 실행할 수 있습니다. C 확장의 경우 Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS 매크로를 사용하여 명시적으로 GIL을 관리합니다.