파이썬에서 GIL이란 무엇입니까? Python의 다중 처리.

당신이 누구든, 어디서 왔는지에 관계없이 우리 모두가 동의할 수 있는 한 가지는 Finding Nemo이 절대적인 걸작(10/10)이라는 것입니다. 아직 안 보신 분들은 이 글은 물론 보시고 바로 보시는 걸 추천드립니다 :)

기억하시겠지만 니모를 찾아서에는 GILL (Moorish Idol fish)이라는 캐릭터가 있었습니다. 영화에서 GILL은 어항 안에서 리더 역할을 했습니다. GILL은 모든 중요한 결정을 내리고 어항의 개선을 위해 미래를 계획했습니다.

오늘 논의하는 GIL(Global Interpreter Lock)은 Python의 메모리 관리 시스템을 중심으로 개발된 메커니즘인 Python에서도 매우 유사한 역할을 합니다. GIL은 항목을 순서대로 유지하고(이 경우 메모리 누수 및 경합 상태 방지) 많은 항목을 더 간단하고 깔끔하게 만듭니다. 그러나 모든 반짝임이 금이 아닌 것처럼 GIL도 특히 컴퓨팅 집약적인(CPU 바인딩) 무언가를 작성하려는 경우 몇 가지 문제가 있습니다.

조금 더 깊이 들어가 보겠습니다(Python의 GIL 메커니즘).



프로그래밍 언어에서 컴퓨팅 집약적인 작업을 수행하려는 경우 머리에 가장 먼저 떠오르는 솔루션은 스레드입니다. Python에서는 스레딩 모듈을 활용할 수 있지만 수행 중인 작업이 I/O 바인딩(디스크 읽기 및 쓰기, 네트워크 작업 수행)인 경우에만 적합합니다. 이는 GIL(Global Interpreter Lock)이 주어진 시간에 하나의 스레드만 실행 상태에 있도록 허용하기 때문입니다. 따라서 컴퓨터에 8개의 코어가 있는 경우 계산을 위해 모든 코어를 활용할 수 없습니다.

이 시점에서 GIL이 왜 이렇게 설계되었는지 자문할 수 있습니다. Python은 참조 카운트 메커니즘을 사용하여 메모리를 관리합니다. 즉, 변수의 참조 카운트가 0에 도달하면 자동으로 정리됩니다. 여러 면에서 이것은 개발자의 삶을 훨씬 더 단순하게 만듭니다.

# Variable name is cleaned up immediately after the 
# execution of function scope, as reference count reaches zero
def the_coolest_function_ever():
   name = "Aamir"


# ==== Let's take a slightly involved example =====


# In the following function planet_name will not be 
# cleaned, as at the end of the function scope the 
# reference count of planet_name will be greater than 0
def boot_planet(planet_name):
   print("Booting....")

   # planet_name Ref-count => 3
   print(planet_name)



def main():

   # planet_name Ref-count => 1
   planet_name = "Mars"

   # planet_name Ref-count => 2
   boot_planet(planet_name)


위의 코드 스니펫에서 볼 수 있듯이 참조 카운팅 시스템은 메모리 관리와 관련하여 일을 훨씬 더 간단하게 만들어 개발자가 메모리 획득 및 해제에 대해 걱정하는 대신 앱에 더 집중할 수 있도록 합니다.

그러나 둘 이상의 스레드가 동시에 변수에 액세스하려고 하면 참조 카운트 메커니즘이 변수의 참조 카운트를 잘못 증가 또는 감소시켜 스레드 경합 상태가 발생할 수 있습니다. 이로 인해 변수가 정리되지 않은 상태로 남아 메모리 누수가 발생할 수 있으며, 잘못된 시간에 변수가 정리되면 응용 프로그램이 중단될 수 있습니다.

이것은 Python의 GIL 메커니즘이 들어오는 곳이며 GIL(Global Interpreter Lock)의 역할은 주어진 시간에 단일 스레드만 변수 및 데이터 구조에 액세스할 수 있도록 하는 것입니다. 이것은 모든 불쾌한 스레드 경쟁 조건과 참조 카운팅 변수의 잘못된 수정을 방지합니다.

여기서 주목해야 할 점은 GIL(Global Interpreter Lock)이 스레드로부터 안전한 데이터 액세스를 위해 다양한 프로그래밍 언어에서 사용하는 다른 잠금 메커니즘과 다르다는 것입니다. 개별 변수와 데이터 구조를 잠그는 다른 잠금 메커니즘과 달리 GIL은 Python 인터프리터 자체를 잠그는 잠금 장치입니다. 즉, 실행이 필요한 모든 Python 코드는 명시적으로 GIL 잠금을 획득해야 합니다. 결과적으로 모든 CPU 바인딩 응용 프로그램의 단일 스레드 실행이 발생합니다.

GIL과 함께 행복하게 살기 (Bypassing GIL)



GIL을 우회하는 방법에는 여러 가지가 있습니다. 첫째, GIL 메커니즘은 원래 CPython 구현에만 존재하고 Jython 및 IronPython에는 존재하지 않습니다. 종속 라이브러리와 함께 애플리케이션이 다른 Python 구현에서 사용 가능한 경우 이를 사용할 수 있습니다. GIL에 대해 걱정하지 않고 통역사.

두 번째로, 각각 고유한 인터프리터가 있는 메모리에서 여러 Python 프로세스를 실행하는 Python의 다중 처리 모듈을 활용할 수도 있습니다. 그러나 프로세스 생성 및 시작은 여러 스레드를 시작하는 것보다 여전히 무겁습니다.

Nothing in life is to be feared, it is only to be understood. Now is the time to understand more, so that we may fear less. Marie Curie

좋은 웹페이지 즐겨찾기