1. 程式人生 > >GIL-全域性解釋鎖

GIL-全域性解釋鎖

GIL全域性解釋鎖

在python中,存在一個GIL全域性解釋鎖,這個鎖並不是python特有的,而是cpython所有的,cpython是python的c語言寫的直譯器,使用jpython就不會出現GIL的問題

如果使用的多程序,程序與執行緒不同,程序與程序的記憶體空間是相互獨立的,雙核的cpu可以同時處理兩個程序,因此如如果執行的是兩個程序程式

from multiprocessing import Process

def run1():
    while True:
        pass
def run2():
    while True:
        pass
if __name__ == '__main__': p1 = Process(target=run1) p2 = Process(target=run2) p1.start() p2.start()

程式碼明顯是死迴圈,而且使用的最快的方式進行死迴圈,一旦啟動,兩個程序都進入死迴圈,那麼使用的虛擬機器上模擬雙核系統的linux系統中開啟htop命令可以看到雙核cpu都進入100%的模式

如果使用的是多執行緒操作程式碼

import threading

def run1():
    while True:
        pass
def run2
(): while True: pass if __name__ == '__main__': p1 = threading.Thread(target=run1) p2 = threading.Thread(target=run2) p1.start() p2.start()

使用的是多執行緒操作,同樣的方式觀察cpu佔用,發現實際上兩個cpu都只佔用的是50%,講道理這兩個執行緒也可以放在兩個cpu中進行執行,死迴圈的執行效率非常高,應該直接就100%.那麼這裡只有50%就說明cpu沒有被完全佔用.

同樣是python中,多執行緒和多程序就存在這樣的差異.這不是python本身的問題,而是cpython這個直譯器本身具有的問題,cpython採用的是全域性解釋鎖的方式進行執行多執行緒的操作

cpu的運算本身是一次只能執行一個程式,因為存在時間片輪轉的方式進行執行,在時間極段的情況下進行執行輪轉,看起來就像是同時執行了多個程式一樣.那麼多核的cpu則執行的是多個程式,而cpython最坑的地方就是在於對執行緒的處理,無論是多少個cpu在cpython面前都沒有卵用,cpython會截斷所有執行緒直接進入cpu,而是由cpython來分配,類似於cpython執行時間輪轉一樣,一次只允許一個執行緒進入cpu執行,就算有多個cpu也沒有卵用,其他cpu就算是空閒狀態,cpython也不會允許在第一個執行緒沒有執行完成退出cpu的情況下放一個執行緒進其他cpu

這就導致雙核的cpu實際上每次只有一個cpu在執行執行緒,另外一個是閒置,當時間片輪轉到下一個時,原本執行的執行緒被彈出,cpython將放下另外一個執行緒去cpu執行,此時這個執行緒是進第一個cpu執行還是第二個cpu,這個是cpython本身不可控的,由於程式執行非常快,對大量的處理而言這個執行緒進入任意一個cpu的可能性就是核數分之1,因為有兩個核,所以是50%,而程式是死迴圈,快速執行,會直接佔滿cpu,因此會在htop裡面看到cpu佔用率都是50%,那麼如果是4核,就會看到佔用率為25%.以此類推

python要解決這個問題是沒有辦法的,python本身是不能解決的,要想解決需要呼叫c語言寫的程式包.老子不會寫c…那就沒辦法,徹底GG,當然換個沒有全域性解釋鎖的直譯器也可以,不過官方推薦的cpython,你懂的