동현 유
척척석사
동현 유
전체 방문자
오늘
어제
  • 분류 전체보기 (181)
    • BlockChain (48)
      • [paper] Consensus (13)
      • [paper] Execution (19)
      • [paper] Storage (5)
      • [paper] ZKP (1)
      • [paper] Oracle (1)
      • Blockchains (9)
    • Java (19)
      • Java의 정석 (13)
      • Java 파헤치기 (5)
    • Python (20)
      • Python 뜯어보기 (6)
      • 데이터 분석 기초 (5)
      • Python 기초 강의 (6)
      • Python 기초 강의 부록 (3)
    • Golang (0)
    • MySQL (3)
      • programmers (2)
      • 기본 문법 (0)
    • 웹 프로젝트 (IBAS) (36)
      • Django 레거시 (14)
      • SpringBoot api 개편 (14)
      • Infra (3)
      • 서버 장애 기록 (4)
      • 신입팀원 교육 자료 (1)
    • CS (30)
      • Operating System (22)
      • Computer Security (3)
      • Network (4)
      • DBMS (1)
    • 책 (10)
      • 도메인 주도 설계 철저 입문 (9)
      • Real MySQL 8.0 (1)
    • BOJ 문제 풀이 (3)
    • 이러쿵저러쿵 (10)
    • 회고 (1)

인기 글

최근 댓글

최근 글

hELLO · Designed By 정상우.
동현 유

척척석사

[Python 뜯어보기] 3. 파이썬 Thread 와 GIL
Python/Python 뜯어보기

[Python 뜯어보기] 3. 파이썬 Thread 와 GIL

2022. 3. 22. 17:01
자료 출처: http://www.dabeaz.com/python/UnderstandingGIL.pdf

 

1. Thread Execution Model (with GIL)

- 파이썬을 실행시키면 => 하나의 프로세스, 하나의 인터프리터

- 파이썬 쓰레드는 real system(os) thread 이다.(unix 계열 posix thread, window 계열 window thread.)
완전히 os 가 관리한다.

- GIL(global interpreter lock): 한 프로세스에는 여러 스레드가 존재할 수 있는데, 한 스레드가 인터프리터를 사용할 때 다른 쓰레드는 인터프리터를 사용할 수 없다. (인터프리터를 사용한다는 말은 파이썬 코드를 해석->실행시킨다는 말)

- 즉 한 스레드가 cpu bound job 을 수행할 때는 GIL 이 해당 스레드에 acquired 되고 다른 쓰레드에는 lock 된다.

- GIL 을 소유한 스레드가 io bound job 을 수행할 때는 GIL 이 release 된다. (파이썬 코드를 실행할 필요가 없으므로.)

- 일정 cpu 타임(100 tick)마다 다른 쓰레드의 요청을 대기 큐로부터 확인한다. 보통은 FIFO 이지만 os scheduler 에 따라 우선순위가 가장 높은 쓰레드가 점유하게 된다. (os 의 스레드가, 완전히 os 가 관리하는 듯) 

 

- 위와 같이 c binary semaphore 로 구현했다고 한다.

 

 


2. Race Condition on GIL

- 아래는 race condition 이 발생했을 때 GIL 경합 과정이다.

1 2 3
4 5 6

3. GIL battle

(1) GIL battle이란?

  : 멀티코어 환경에서 다른 cpu 에 스레드가 할당되어 있을 때, 싱글코어에 비해서 gil 을 차지하기가 월등히 어려워지는 현상. (http://dabeaz.blogspot.com/2010/01/python-gil-visualized.html) 아래 이미지.

(2) 해결방안

 - 멀티코어에서의 멀티쓰레드 GIL Battle 문제를 해결하기 위해 python 3.2 부터 도입된 방법 : GIL을 기다리는 다른 코어의 쓰레드가 TIME-OUT이 발생할 때마다 gil_drop_request 시그널을 보냄

1 2 3
4 5 6

(3) 한계

- 하지만 위의 방식에도 문제가 여전히 존재함.
   (1) 일단 GIL을 얻기까지 무조건 time-out 단위로 대기해야함 => 응답시간이 길어짐

   (2) Unfair Wakeup/Starvation : 3개 이상의 쓰레드가 존재할 때, 스레드2가 타임아웃으로 시그널을 보낸뒤 ready 상태로 들어가는 동안 다른 스레드가 GIL 을 얻기도 한다. => 응답시간이 더 길어짐.

   (3) convoy effect : read 나 write 와 같이 상대적으로 속도감이 있는 io bound 커널 코드를 실행할 때마다, GIL을 무조건 release하므로, 버퍼사이즈만큼 io 한번하고 timeout 단위로 기다리면서 gil을 다시 획득해야한다. => 응답지연

 

- 위와 같은 이유로, 아래 사진(간단한 echo 프로그램)을 보면, 멀티코어 멀티쓰레드에서 응답지연이 어마어마함을 알 수 있다. 


4. 결론

- 2010 년도 자료라 지금은 어떻게 되었을 지 모르겠지만, 당시 자료에는 GIL 을 없애지는 않겠다고 적혀있다.

- 추가로, io bound 스레드와 cpu bound 스레드를 분리하거나, preemption 에 대한 우선순위를 정하는 등의 개선이 이루어질 것이라고 적혀있었음. 

- 그래도 GIL 의 특성상 single thread 가 훨등히 빠를수 밖에.

- 굉장히 긴 io 작업에 대해서만 쓰레드를 사용하는 게 좋겠다.

'Python > Python 뜯어보기' 카테고리의 다른 글

[Python 뜯어보기] 5. 파이썬 가상머신(PVM) 과 컴파일방식  (0) 2022.04.13
[Python 뜯어보기] 4. WSGI 와 Python  (0) 2022.03.22
[Python 뜯어보기] 2.극한의 '객체'충 파이썬  (0) 2021.03.17
[Python 뜯어보기] 1. 파이썬은 어떻게 문장을 인식할까?  (0) 2021.03.10
[Python 뜯어보기] 0. 파이썬을 공부하기로 결심한 이유  (0) 2021.03.10
    동현 유
    동현 유
    Fault Tolerant System Researcher for more Trustful World and Better Lives. (LinkedIn: https://www.linkedin.com/in/donghyeon-ryu-526b8a276/)

    티스토리툴바