일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 데이터파이프라인
- 하둡
- 데이터엔지니어링
- 하둡1.0
- 프로그래머스 큰 수 만들기
- AWS Crawler
- 런타임데이터영역
- 문맥교환
- Spark 최적화
- 서버간 복사
- Databricks
- Spark
- ORACLE문법
- EMR 구조
- 카프카
- 데이터베이스복사
- 지연연산
- kafka 설치
- freenom
- 프로그래머스
- 실행엔진
- 스파크
- 데이터 수집
- lazy evaluation
- 빌드도구
- 하둡에코시스템
- Catalyst Optimizer
- 하둡2.0
- 프로그래머스힙
- ORACLE MSSQL차이
- Today
- Total
띵유로그
[파이썬] 파이썬 전역 인터프리터 락 (GIL) 본문
파이썬 주요 특징중 하나는 GIL(Global Interpreter Lock) 입니다.
GIL 이란?
파이썬의 최초 구현체는 CPython 인데,
CPython은 스레드세이프 하지 않기때문에 메모리 관리를 쉽게 하기 위해서 GIL로 파이썬 객체에 접근을 제한 했습니다.
일종의 Mutex인 셈입니다.
GIL이 필요했던 이유
Python 은 모든 것이 객체입니다.
Python 객체는 참조횟수를 저장하고 있습니다. 저장해둔 참조 횟수에 따라서 GC(Garbage Collection)을 하게 됩니다.
참조횟수가 0이면 자동으로 메모리에서 삭제해주는 것입니다.
참조횟수는 sys의 getrefcount 함수를 통해서도 확인할 수 있습니다.
>>> import sys
>>> a = []
>>> b = a
>>> sys.getrefcount(a) # getrefcount 에서 참조하기 때문에 +1이 됨 함수 return 하고나면 다시 -1
3
그런데, 만약 스레드세이프하지 않다면(여러개의 스레드가 상호배제없이 동시에 실행된다면) 참조횟수는 제대로 관리되지 않을 것입니다. 이런 상황을 Race Condition이라고 부릅니다.
이를 해결하려면 모든 객체를 mutex로 잠궈야합니다. 하지만 객체를 모두 mutex로 잠구는 것은 비효율적입니다.
그래서 Python은 아예 하나의 쓰레드가 인터프리터를 실행하고 있으면, 다른 쓰레드는 인터프리터를 실행하지 않도록 해버렸습니다. 모든 객체를 잠구는 대신 인터프리터를 잠궈버린것입니다. 이러한 방법을 GIL 이라고 합니다.
GIL 의 문제
GIL은 코어가 하나밖에 없던 초기에는 아무런 문제가 없었습니다.
하지만 이제는 멀티코어가 당연해졌으니 많은 문제가 생기게 되었습니다.
GIL 때문에 파이썬 인터프리터는 한 시점에 하나의 쓰레드에 의해서 밖에 실행되지 못합니다.
멀티스레딩은 불가능한가?
멀티스레딩이 불가능한 것은 아닙니다.
CPU연산이 있는 작업의 경우에는 참조횟수을 보호하기 위해 GIL의 영향을 받아 쓸데없이 문맥교환만 하게 되지만
I/O와 sleep의 경우 참조횟수변수에 영향을 주지 않기 때문에 멀티스레딩의 효과를 볼 수 있습니다.
또 병렬처리가 필요할 때 스레드가 아닌 멀티 프로세싱을 통해서도 해결할 수 있습니다.
스레드로 처리가 필요하다면 CPython 이 아닌 Jypthon, PyPy 등도 고려할 수 있습니다.