GIL全域解釋器鎖
1、什么是GIL全域解釋器鎖
GIL:Global Interpreter Lock,意思就是全域解釋器鎖,這個GIL并不是Python的特性,他是只在Cpython解釋器里引入的一個概念,而在其他的語言撰寫的解釋器里就沒有GIL,例如:Jython,Pypy等
下面是官方給出的解釋:
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)
翻譯過來的意思就是:在CPython中,全域解釋器鎖(GIL)是一個互斥鎖,可以防止多個本地執行緒同時執行Python位元組碼,這個鎖是必要的,主要是因為CPython的記憶體管理不是執行緒安全的,(但是,由于GIL存在,其他特性已經發展到依賴于它所執行的保證,)
所以:
GIL本質上就是一把互斥鎖,用來保證資料的正確性,使資料可以正常同步,
GIL就像是BUG一般存在的全域互斥鎖,目前無法通過代碼去除GIL
結論:在CPython解釋器中,在同一個行程下開啟的多執行緒,同一時刻只能有一個執行緒執行,無法利用多核優勢
PS:我們平常所使用的python是C語言撰寫的,所以大部分人所說的python也指CPython,CPython是python的官方版本,若是指其他語言寫的python,一般情況下會指明,如Jypthon、Pypy等
2、為什么會出現GIL
隨著電腦多核CPU的出現,python為了充分利用多核CPU,進行多執行緒的編程方式便普及了起來,但是隨之而來的困難是執行緒之間資料的一致性和狀態同步,python為了解決這個資料不能同步的問題,所以設計了GIL全域解釋器鎖,其實就是互斥鎖
說到互斥鎖,在多執行緒互斥鎖中共享全域變數的時候會有執行緒對全域變數進行的資源競爭,會對全域變數的修改產生不是我們想要的結果,而那個時候用到的是python中執行緒模塊里面的互斥鎖,
如下例(未加執行緒互斥鎖):
from threading import Threadimport time n = 100 def task(): global n m = n time.sleep(0.5) # 模擬IO操作 n = m - 1 if __name__ == '__main__': list1 = [] for i in range(10): t = Thread(target=task) t.start() list1.append(t) for t in list1: t.join() print(n)
執行結果:
99
在上面的例子里,我創建了10個執行緒來爭奪對 n 進行 -1 操作,但是結果并非我想要的,所以我在這里加入了互斥鎖
如下例(加執行緒互斥鎖):
from threading import Thread from threading import Lock import time n = 100 def task(lock): global n lock.acquire() # 加鎖 m = n time.sleep(0.5) # 模擬IO操作 n = m - 1 lock.release() # 解鎖 if __name__ == '__main__': list1 = [] lock = Lock() for i in range(10): t = Thread(target=task, args=(lock, )) t.start() list1.append(t) for t in list1: t.join() print(n)
執行結果:
90
這次就可以得到我想要的結果,在前面我的行程和執行緒的博文里也說到過這個問題,
3、GIL的優缺點
優點:
保證資料的正確性
缺點:
單個行程下,開啟多個執行緒,犧牲了執行效率,無法實作并行,只能實作并發
4、如何體現GIL全域解釋器鎖
在Cpython解釋器中,當python代碼有一個執行緒開始訪問解釋器的時候,GIL會把這個大鎖給鎖上,此時此刻其他的執行緒只能干等著,無法對解釋器的資源進行訪問,這一點就和互斥鎖相似,而只是這個程序發生在我們的Cpython中,同時也需要等這個執行緒分配的時間到了,這個執行緒把GIL釋放掉,類似互斥鎖的lock.release()一樣,另外其他的執行緒才開始跑起來,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/206927.html
標籤:其他
上一篇:Django之簡易用戶系統(3)
