Python은 GIL 을 통해 한 번에 하나의 스레드만 실행하도록 제한한다.
⇒ CPython Interpreter 에서 하나의 스레드만 동시에 Python 바이트코드를 실행하도록 제한하는 lock 이다.
[Why]
CPython ⇒ 거의 대부분이 Cpython
⇒ CPython은 numpy, pandas, tensorflow, scikit-learn 등…
💡 문득 V2… Pyspark도 CPython에서 동작…?
내가 궁금한거..? Spark JVM의 Spark Context를 조작..?
⇒ 그런데 CPython인가?
- Pyspark에서 CPython의 역할
1. PySpark 애플리케이션 시작
⇒ `SparkSession` 객체 생성 및 데이터 읽기, 데이터 표시는 **CPython** 환경에서 수행
2. Python API 호출
⇒ PySpark는 Python API를 제공하며 PySpark의 메서드를 호출 시,
2-1. CPython은 PySpark Python API 에서 제공하는 메서드와 클래스를 호출
2-2. 이 때, CPython은 PySpark Python API에서 제공하는 메서드와 클래스를 호출하고, 이를 Java Context로 전달하기 위한 `Py4J` 를 통해 JVM과 상호작용함.
Jython
IronPython
⇒ 차이 : “어떤 언어로 작성되어 Python 언어를 저수준 언어로 바꾸냐?”
이 때, 대부분 사용하는 CPython은 참조 카운트(Reference Counting) 기반의 메모리 관리(Garbage Collection)을 사용
Reference Counting
파이썬에서 중요한 메모리 관리 기법
특정 객체의 Reference Count가 0이 되면 객체의 메모리 0이 할당되는 방식
Garbage Collection
누군가 객체를 더 이상 참조하지 않으면 동적 할당된 영역 가운데 더 이상 사용할 수 없게 된 영역을 탐지하여 자동으로 해제하는 기법

del 키워드로 변수 삭제
a <= [1, 2, 3]
del a # a라는 이름과 해당 객체의 참조가 제거됨
참조를 다른 객체로 덮어쓰기
a = [1, 2, 3]
a = None # 기존 리스트에 대한 참조를 버리고 None 객체로 덮어씀
a가 참조하던 [1, 2, 3] 객체는 참조 수 -1함수 호출 종료로 인한 지역 변수 소멸
def make_list():
a = [1, 2, 3] # 지역 변수
make_list() # 함수가 끝나면 a도 소멸 → 참조 해제
a라는 이름은 스택에서 사라지므로 참조도 해제됨.컨테이너에서 요소 제거
a = [[1, 2], [3, 4]]
del a[0] # 첫 번째 리스트에 대한 참조 제거
확인용 - sys.getrefcount()
import sys
a = [1, 2, 3]
print(sys.getrefcount(a)) # 보통 2 (하나는 a, 하나는 함수 인자)
python에서

변수는 stack에 ⇒ GC 대상이 아님
객체는 heap에 저장 ⇒ GC 대상
⇒ 다수의 스레드가 동시에 객체의 참조 카운트를 변경하면 Race Condition(경쟁 조건) 발생 가능
[Problem]
[Solve]
⇒ 이렇기 때문에 GIL 을 도입하여 GC based on Reference Count를 안전하게 관리가 가능함.
I/O 작업일 때는 GIL 이 해제되긴 함.
requests , socket , open().read() → 디스크나 네트워크 통신하는 I/O 작업
- python naming rule : https://wikidocs.net/80544