파이썬의 쓰레드는 진짜 쓰레드가 아니다.

KANG SANG MIN
2 min readDec 18, 2019

--

사실 파이썬의 멀티 스레딩은 진정한 의미의 멀티 스레딩이 아닙니다. 스레드를 아무리 늘려도 한 프로세스 내에서 특정 순간에 한 스레드만 실행이 됩니다. 아무리 코어가 많은 머신이라도 이 상황은 동일 합니다. 파이썬 웹 프레임워크가 성능 벤치에서 항상 하위권을 면치 못하는 이유 이기도 합니다. 같은 인터프리터인 node.js에 비해서도 느리죠. 이 문제에 대한 해답으로 비교적 최근에 추가된 asyncio(coroutine)으로 시간을 효율적으로 분배하여 성능을 최대한 끌어 올리고는 있지만 진정한 멀티 스레딩이라 하긴 힘듭니다. 그래서 파이썬 앱을 설계/배포 할때는 일반적으로 멀티 스레딩 보다 멀티 프로세싱으로 하드웨어 자원을 최대한 활용하는 방식을 선택합니다. 이게 다~ GIL 때문입니다. 이에 관한 좋은 글이 있어 공유 합니다.

요약 하자면 우리가 일반적으로 사용하는 CPython은 한 프로세스당 하나의 인터프리터만 존재합니다. 여러 컨텍스트가 인터프리터를 사용하기 위해 경쟁하는 상황을 방지하기 위해 GIL(Global Interpreter Lock)을 도입 하여 현재 어떤 컨텍스트가 인터프리터를 사용하고 있는지 관리하게 됩니다. 이는 개발자들로 하여금 쓰레드 프로그래밍을 거의 신경쓰지 않고 할 수 있도록 단순화 시켜주는 엄청난 장점이 있습니다. 하지만 GIL을 통해서 실행 중인 컨텍스트를 제외한 다른 모든 컨텍스트들은 대기하게 됩니다. 쓰레드가 아무리 늘어나도 단일 인터프리터를 통해서 실행되기 때문에 결국 쓰레드가 의미가 없다는 것입니다.

이러한 구조적인 문제를 해결하기 위해 PEP554에서는 서브 인터프리터를 제안 하였습니다. 단일 프로세스 내에서 여러 스레드가 구동될 수 있도록 서브 인터프리터를 두게끔 하는 방식입니다. 이 제안이 merge 된다고 해도 그간 동시 구동을 염두에 두지 않고 작성된 많은 라이브러리들이 제대로된 지원을 하기 전까지 완전한 멀티 쓰레딩은 요원할지 모릅니다. 하지만 그 기반이 마련된다는 점에서 한 단계 더 나아가게 되는 것 만은 확실 합니다.

3.8~3.9 사이에 구현이 완료될 예정이라 하니 그 간에 3.8로 업그레이드도 준비하고 배포 설정도 멀티 프로세스로 전환하면서 다 같이 상황을 지켜 봅시다.

--

--