關於 Python 多執行緒/多程式

weixin_33936401發表於2017-01-07

src:http://m.blog.csdn.net/article/details?id=51243137

Python 下有一個GIL,用來保證每次直譯器只在解釋一個檔案。所以,在單核CPU下的多執行緒其實都只是併發,不是並行,併發和並行從巨集觀上來講都是同時處理多路請求的概念。但併發和並行又有區別,並行是指兩個或者多個事件在同一時刻發生;而併發是指兩個或多個事件在同一時間間隔內發生。

但是在處理 IO 密集型的時候,用多執行緒可以提高程式執行的效率。

如果是 CPU 密集型的程式,還是要使用多程式。

試試用Python寫個死迴圈:

import threading, multiprocessing
def loop():
  x = 0 
  while True: 
    x = x ^ 1

for i in range(multiprocessing.cpu_count()): 
  t = threading.Thread(target=loop) 
  t.start()

啟動與CPU核心數量相同的N個執行緒,在4核CPU上可以監控到CPU佔用率僅有160%,也就是使用不到兩核。
即使啟動100個執行緒,使用率也就170%左右,仍然不到兩核。
但是用C、C++或Java來改寫相同的死迴圈,直接可以把全部核心跑滿,4核就跑到400%,8核就跑到800%,為什麼Python不行呢?
因為Python的執行緒雖然是真正的執行緒,但直譯器執行程式碼時,有一個GIL鎖:Global Interpreter Lock,任何Python執行緒執行前,必須先獲得GIL鎖,然後,每執行100條位元組碼,直譯器就自動釋放GIL鎖,讓別的執行緒有機會執行。這個GIL全域性鎖實際上把所有執行緒的執行程式碼都給上了鎖,所以,多執行緒在Python中只能交替執行,即使100個執行緒跑在100核CPU上,也只能用到1個核。
GIL是Python直譯器設計的歷史遺留問題,通常我們用的直譯器是官方實現的CPython,要真正利用多核,除非重寫一個不帶GIL的直譯器。
所以,在Python中,可以使用多執行緒,但不要指望能有效利用多核。如果一定要通過多執行緒利用多核,那隻能通過C擴充套件來實現,不過這樣就失去了Python簡單易用的特點。
不過,也不用過於擔心,Python雖然不能利用多執行緒實現多核任務,但可以通過多程式實現多核任務。多個Python程式有各自獨立的GIL鎖,互不影響。

相關文章