[Python] GIL

2021. 3. 4. 22:54·Language/Python
반응형
[Phthon] GIL

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

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

xxxxxxxxxx
def factorize(n):
    for i in range(1, n + 1):
        if n % i == 0:
            yield i
​
import time
numbers = [135254,134135,543554,2436245]
start = time.time()
​
for n in numbers:
    list(factorize(n))
​
end = time.time()
d = end - start
print(f"{d:.3f}s...")
xxxxxxxxxx
0.201s...

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

x
from threading import Thread
class FactorizeThread(Thread):
    def __init__(self, number):
        super().__init__()
        self.number= number
​
    def run(self):
        self.factors = list(factorize(self.number))

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

x
threads = []
for n in numbers:
    thread = FactorizeThread(n)
    thread.start()
    threads.append(thread)
​
# 모든 쓰레드가 종료될 떄 까지 대기
for t in threads:
    t.join()

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

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

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

 

Ref

  • 파이썬 코딩의 기술
  • https://dgkim5360.tistory.com/entry/understanding-the-global-interpreter-lock-of-cpython
  • https://jeongukjae.github.io/posts/python-GIL/
반응형
저작자표시 비영리 변경금지 (새창열림)
'Language/Python' 카테고리의 다른 글
  • [Python] ensure_future
  • [Python] Queue
  • [Python] Flask
  • [Python] 함수 인자
덴마크초코우유
덴마크초코우유
IT, 알고리즘, 프로그래밍 언어, 자료구조 등 정리
    반응형
  • 덴마크초코우유
    이것저것끄적
    덴마크초코우유
  • 전체
    오늘
    어제
    • 분류 전체보기 (126)
      • Spring Framework (10)
        • Spring (5)
        • JPA (3)
        • Spring Security (0)
      • Language (52)
        • Java (12)
        • Python (10)
        • JavaScript (5)
        • NUXT (2)
        • C C++ (15)
        • PHP (8)
      • DB (16)
        • MySQL (10)
        • Reids (3)
        • Memcached (2)
      • 개발 (3)
      • 프로젝트 (3)
      • Book (2)
      • PS (15)
        • 기타 (2)
        • 백준 (2)
        • 프로그래머스 (10)
      • 딥러닝 (8)
        • CUDA (0)
        • Pytorch (0)
        • 모델 (0)
        • 컴퓨터 비전 (4)
        • OpenCV (1)
      • 기타 (16)
        • 디자인패턴 (2)
        • UnrealEngine (8)
        • ubuntu (1)
        • node.js (1)
        • 블로그 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    클래스
    memcached
    자바
    게임 개발
    프로그래머스
    mscoco
    FPS
    CPP
    redis
    Unreal
    map
    언리얼엔진4
    C
    MySQL
    JavaScript
    C++
    알고리즘
    게임
    딥러닝
    JS
    웹
    파이썬
    NUXT
    블루프린트
    PS
    pytorch
    Unreal Engine
    select
    Python
    php
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
덴마크초코우유
[Python] GIL
상단으로

티스토리툴바