Skip to content

[python] GIL(Global Interpreter Lock) and Releasing it in C extensions

Myungchul Shin edited this page Feb 23, 2015 · 11 revisions

GIL(Global Interpreter Lock)

Releasing GIL in C extensions

Notes

  • 내용을 읽어보면 알겠지만, python의 threading을 사용해서 멀티쓰레드를 생성하면 실제로 thread들이 생성되고 실행되기는 한다. 하지만, GIL로 인해서 코어는 여러개지만 한순간 하나의 thread만 동작이 가능하다. 예외적으로 I/O operation을 호출할때는 lock을 release하는데, 이때 다른 thread가 동작하게되면 순간적이긴 하지만 두개의 thread가 동시에 동작하는 것처럼 보인다.(I/O도 일을 하긴 하는 것이니까) 물론, I/O는 python 코드가 아니므로 interpreter 입장에서는 동시에 실행되는 것은 아니지만, 전체적인 관점에서 그렇다는 얘기다. 따라서, I/O 연산이 많은 부분을 차지하는 경우 threading을 사용하면 효과를 볼 수 있다. CPU-bound 연산인 경우는 오히려 thread를 사용 안하는 경우가 더 빠르겠지만...
  • 나의 경우 C로 개발된 라이브러리를 python extension으로 만들어서 사용하는 경우가 많은데, 라이브러리 자체에 thread-safty가 보장되지 않는 경우 multi-threading 실행하는 경우 어떻게 될까? C 라이브러리에서 공유하는 writable data structure가 존재하는 경우 당연히 thread-safty는 보장될 수 없다. read-only인 경우라면 상관없겠지만...
  • 따라서, thread-unsafe C 라이브러리를 사용해서 multi-thread로 동작하는 python 프로그램을 작성하는 경우는 특별한 조치 없이는 불가능하다. 여기서 말하는 특별한 조치란 writable data structure를 thread의 개수만큼 여러개를 둬서 개별 thread가 하나씩 사용하는 하는 것과 같이 일반적으로 사용되는 테크닉을 의미한다. 이런 방식으로 C 라이브러리를 수정했다면 python extension에서 그것에 맞게 코드를 수정하고 GIL을 명시적으로 릴리즈하면 어느정도까지는 multi-thread에서 이득을 얻을 수 있을 것이다.
  • 하지만, multi-processing이 있는 상태에서 굳이 이렇게까지 할 이유는 없을 듯...
  • <첨언> thread-safty가 보장되지 않는 C 라이브러리를 extension으로 만들고, 그것을 apache+mod_python 환경에서 multi-processing+multi-threading 설정으로 구동시키는 경우가 있다. 이런 경우는 결과가 잘 나온다고 해도 우연일 뿐이고 multi-threading 부분을 disable시키는 것이 당연한 조치일 것이다. tornado의 경우, 별도의 thread를 생성시켜 callback으로 처리하지 않는 이상 C 라이브러리의 thread-safty 여부는 특별히 신경쓰지 않아도 좋다.(single-thread based) 잘 이해가 안간다면 '이것'을 참조.
Clone this wiki locally