Python 的 GIL (Global Interpreter Lock)

前幾個月在做專案的時候,發現用 mod_wsgi + web.py 寫的程式,理論上支援 multi-thread,應該可以完全利用在多核 CPU Server 的優勢;但實際上跑的時候,會有沒辦法把 CPU Resource 吃完的問題。當時因為時間很趕,想到的解法就是多跑幾個 Process:

<VirtualHost *:80> 
   DocumentRoot “/srv/web/webroot" 
   ServerName python.example.com 
   WSGIProcessGroup pythonexample 
   WSGIDaemonProcess pythonexample processes=16 threads=128 maximum-requests=1024 display-name=%{GROUP}
</VirtualHost>

COSCUPlwhsu 聊到這件事,他講到 CPython 的 GIL,回來查了一下果然就是這個原因。剛好 Web 不需要在每個 thread 之間互相傳資料,所以可以直接用多個 Process 解掉這個問題。

雖然 Python 在執行前就把程式碼轉成 byte code了,但因為這個 Lock 是實做在 CPython 的 Bytecode Interpreter 裡面,所以導致了同時只會有一個 thread 執行 Python bytecode,也因此無法利用到多核 CPU 的優勢1

除了多跑幾個 Process 之外,也可以用 ctypes 配合用 C 寫的 library 來解決這個問題,不過以 Web 應用來說,寫 C 的機會不高就是了。

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone
  1. Stackoverflow: Python threading and gil []