[Python] GIL

GIL, Global Interpreter Lock

멀티스레드 환경에서는 여러스레드에서 동시에 객체에 접근하려 하는 동기화 문제(Race Condition)가 발생할 수 있습니다.

이를 해결하기 위해 스레드가 객체에 접근하는 것을 막기 위한 Mutex/Semaphore 가 필요합니다.

C에서 Thread를 사용할 때, 멀티스레드 환경에서 Race Condition이 일어나지 않도록 하는 것을 개발자에게 맡깁니다.

반면, Python은 GIL를 통해 인터프리터가 한 스레드만 하나의 바이트코드를 실행시키도록 Lock을 겁니다.

Python 메모리 관리

Python이 할당된 메모리를 관리하는 기본적인 방식 두 가지가 있습니다.

  • Garbage Collection

  • Reference Counting

이 중 Reference Counting 은 생성되는 개체의 reference 를 세어가며 메모리를 관리하는 것인데, 이 과정에서 race condition 이 일어나면 memory leak 가 발생할 수 있습니다.

문제를 해결하기 위해 모든 객체에 Lock이 필요하게 되는데 여러 개의 mutex를 사용하는 것은 성능적으로 손해가 될 수 있을 뿐 아니라 Deadlock 을 야기할 수 있게됩니다.

위와 같은 비효율을 막기 위해 Python은 GIL을 사용합니다.

이로 인해 Python 에서 threading 라이브러리나 concurrent 라이브러리로 멀티스레딩을 하더라도, 실제로는 하나의 스레드만이 동작하게 되고 멀티스레드처럼 보이지만 thread context switch 비용만 발생할 뿐 오히려 싱글스레드보다 시간이 오래 걸리게 될 수 있습니다.

그렇다면 Python 에서 비동기 프로그래밍을 하려면 어떻게 해야 할까 의문이 생깁니다.

Python 비동기 프로그래밍

Python 에서 asyncio 라이브러리를 활용하면 비동기 프로그래밍을 제대로 구현할 수 있습니다.

이렇게 되면 C# 에서의 비동기 프로그래밍과 유사하게 Task, await, async 키워드를 이용해 비동기 프로그래밍을 구현할 수 있습니다.

코루틴과 테스크 를 참고하면 좋을 것 같습니다.