라벨이 Global Interpreter Lock인 게시물 표시

[Python] Gil과 Python

지난번 에 언급했듯이 CPython 이나 PyPy 는 Global interpreter lock (a.k.a. GIL)을 이용해서 동시에 2개 이상의 스레드가 실행되지 못하게 함으로써 스레드 간 동기화를 보장한다. 하지만 이는 CPython과 PyPy가 thread를 구현하는 방법일 뿐, Python 스펙에는 동시에 2개 이상의 스레드를 실행시키지 말라거나, GIL을 사용하라거나 하는 말은 없다. 그저 CPython과 PyPy가 효율성을 떨어뜨리더라도 GIL을 사용하는 것이 이득이 되는 것이 많다고 생각해서 GIL을 사용하도록 구현한 것뿐이다. 그래서 Python 구현체 중에서 .net framework 위에서 돌아가는 Iron Python 이나 JVM 위에서 올라가는 Jython 의 경우 GIL을 사용하지 않는다.

Global Interpreter Lock이란?

이미지
GIL 이란? GIL이란 Global Interpreter Lock 의 약자로 여러개의 쓰레드가 있을떄 쓰레드간의 동기화를 위해 사용되는 기술 중 하나이다. GIL은 전역에 lock을 두고 이 lock을 점유해야만 코드를 실행할 수 있도록 제한한다. 따라서 동시에 하나 이상의 쓰레드가 실행되지 않는다. 예를 들어 아래 그림과 같은 3개의 쓰레드가 분산해서 일을 처리하게 될 때도 실제로 CPU를 점유할 수 있는 thread는 한 개뿐이다. 따라서 실제로 사용하는 코어는 하나뿐이라는 것이다. 싱글 코어 컴퓨터에서 multi thread program을 실행하는 모습 같다. GIL의 efficiency 직관적으로 멀티코어에서도 코어를 하나밖에 사용 못 한다면 GIL을 사용해서 multi threads를 지원하는 것은 성능에 큰 문제가 있을 거라고 생각된다. 하지만 이는 대부분의 경우에 큰 문제가 되지 않는다. 정확히 말해서 프로그램은 대부분 I/O bound 이기 때문에 문제가 되지 않는다. I/O bound의 경우 대부분 시간을 I/O event를 기다리는 데 사용하기 때문에 event를 기다리는 동안 다른 thread가 CPU를 사용하면 된다. 반대로 말해서 프로그램이 CPU bound 인 경우에는 multi-threaded program을 작성해도 성능이 향상되지 않는다. 오히려 lock을 acquire하고 release하는 시간 때문에 성능이 떨어지기도 한다. GIL의 장점 멀티 쓰레드 프로그램에서 성능이 떨어질 수도 있지만, CPython , PyPy , Ruby MRI , Rubinius , Lua interpreter 등 많은 인터프리터 구현체들이 GIL을 사용하고 있다. 그 이유는 우선 GIL을 이용한 multi-threads를 구현하는 것이 parallel 한 multi-threads를 구현하는 것보다 훨씬 쉽다는 것이다. 게다가 이런 parallel 한 multi-threads 구현체들의 문제는 싱글 쓰레드에서 오히려...

이 블로그의 인기 게시물

USB 2.0 케이블의 내부 구조

[C++] enum class - 안전하고 쓰기 쉬운 enum

Log Aggregator 비교 - Scribe, Flume, Fluentd, logstash

[Web] SpeechSynthesis - TTS API

[Python] cache 데코레이터로 최적화하기