[Python] GIL

Global Interpreter Lock (GIL)

CPython(파이썬의 표준 구현체)에서 파이썬 코드(bytecode)를 실행할 때 단 하나의 스레드만 접근할 수 있도록 제한하는 mutex

CPython 에서의 메모리 관리: Reference Counting

CPython 에서는 reference 의 갯수를 세는 방법으로 메모리를 관리함.

sys.getrefercount 라는 메소드를 이용해서 특정 object 에 대해 python 이 세고있는 reference 갯수를 확인할 수 있음

import sys
a = []
b = a
sys.getrefercount(a) # print 3

왜 3개냐

  • a가 처음 만들어졌을 때
  • b에 a를 할당했을 때
  • getrefercount 메소드 인자로 들어갔을 때

이 갯수가 0이 되면 CPython 이 알아서 메모리를 회수함

reference counting 으로 인한 문제점

  • CPython은 생성된 객체에 대해 reference 를 세어가면서 메모리 관리를 함
  • 다수의 스레드 사용으로 reference counting 과정에서 race condition 이 생길 수 있음
  • CPython 은 C 로 구현되어 있으므로 race condition 을 막기 위해서는 mutex 를 사용하면 됨
  • 각 객체마다 mutex 를 사용하는 것은 큰 성능 저하로 이어지고 deadlock 발생 가능성도 있음

CPython 의 선택

  • mutex 를 통해 각 객체에 대해 락을 걸지말고, 그냥 인터프리터 자체에 락을 걸자
  • 이것이 GIL (Global Interpreter Lock)
  • 이로 인해 하나의 파이썬 코드에 대해서 하나의 스레드만 동작하게 됨
  • threading 모듈을 사용해도 성능 개선은 커녕 오히려 성능 저하가 일어나는 경우가 있는데, GIL 때문임
  • 파이썬 창시자 귀도는 “단일 스레드 프로그램에서 성능 저하 없이 GIL 의 문제점을 개선할 수 있으면 반영하겠다.” 라고 말했지만, 현재까지 그런 일은 일어나지 않았음

파이썬에서 병렬 처리

  • 병렬처리가 필요한 경우 asyncio 혹은 multiprocessing 을 이용
  • CPython 대신 다른 구현체를 이용하는 것도 방법(PyPy, Jython, etc.)

참고


© 2021. All rights reserved.

Powered by Hydejack v9.1.4