본문 바로가기

Language/파이썬

[Python] GIL

반응형
[Phthon] GIL

CPython은 파이썬의 표준 구현이며 두 단계를 거쳐 파이썬 프로그램을 실행한다. 먼저 소스 코드를 구문 분석해서 바이트 코드로 변환 후, 인터프리터를 통해 실행한다. 이 떄 CPython은 GIL(Global Interpreter Lock)을 사용해 일관성을 강제로 유지한다. 따라서 파이썬에서 멀티 쓰레드 프로그램을 개발하는데는 한계가 있다.

GIL이 멀티 쓰레딩에 어떤 영향을 주는지 코드를 통해 살펴본다. 처리하는데 오래 걸리는 함수를 작성하고 쓰레드를 사용했을 때와 사용하지 않았을 때의 시간을 측정해본다.

4개 수에 대해 인수를 찾는데 약 0.2초가 걸렸다. 이를 멀티 쓰레딩으로 구현해서 시간이 단축되는지 확인해본다.

Thread 클래스를 상속받아 FactorizeThread를 구현한다. 이 클래스를 사용해 각 수에 대한 인수를 구하는데 여러 쓰레드를 사용할 수 있다.

위 코드를 통해 각 수에 대한 인수를 4개의 쓰레드를 사용해 구한다. 위 코드 실행 시간을 측정하면 약 0.2초가 걸린다. 멀티 쓰레드로 구현했음에도 불구하고 기존 코드보다 수행 속도 시간이 단축되지 않았다. 파이썬의 GIL로 인해 하나의 쓰레드만 실행되는 것이다.

그러면 왜 파이썬에서는 GIL을 사용하는 것일까? 가장 근본적인 이유는 레퍼런스 카운팅에 문제를 방지하기 위해서다. 파이썬에서 변수는 참조를 통해 관리된다. 특정 객체를 가리키고 있는 변수가 몇 개인지를 파악하고 해당 객체를 가리키는 변수의 수가 0이면 메모리를 해제한다. 다수의 쓰레드에서 변수들을 서로 사용할 경우 문제가 발생한다. 동일한 변수에 접근할 때 레퍼런스 카운트 변경을 올바르게 하지 못할 수 있다. 이를 방지하기 위해서는 변수 레퍼런스에 대해 뮤텍스 등 상호배제 알고리즘을 적용해야하는데 이는 성능 하락의 원인이 된다. 따라서 파이썬에서는 쓰레드 자체를 방지한 것이다.

파이썬 GIL로 인해 쓰레드 중 하나만 진행할 수 있음에도 쓰레드를 지원하는 이유는 무엇일까? 블로킹 I/O를 다루기 위해서이다. 시스템 콜을 사용할 때 IO를 처리하는 동안 프로그램이 블로킹되는데 응답하는데 걸리는 시간동안 파이썬 프로그램이 다른 처리를 할 수 있다.

 

Ref

반응형

'Language > 파이썬' 카테고리의 다른 글

[Python] ensure_future  (0) 2021.10.23
[Python] Queue  (0) 2021.03.05
[Python] Flask  (0) 2021.01.27
[Python] 함수 인자  (0) 2021.01.20
[Python] Pyenv  (0) 2020.03.24