Cpython解釋器中的GIL全局解釋器鎖
1、什么是GIL全局解釋器鎖
GIL:Global Interpreter Lock,意思就是全局解釋器鎖,這個(gè)GIL并不是Python的特性,他是只在Cpython解釋器里引入的一個(gè)概念,而在其他的語(yǔ)言編寫的解釋器里就沒有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)是一個(gè)互斥鎖,可以防止多個(gè)本地線程同時(shí)執(zhí)行Python字節(jié)碼。這個(gè)鎖是必要的,主要是因?yàn)镃Python的內(nèi)存管理不是線程安全的。(但是,由于GIL存在,其他特性已經(jīng)發(fā)展到依賴于它所執(zhí)行的保證。)
所以:
GIL本質(zhì)上就是一把互斥鎖,用來保證數(shù)據(jù)的正確性,使數(shù)據(jù)可以正常同步。
GIL就像是BUG一般存在的全局互斥鎖,目前無法通過代碼去除GIL
結(jié)論:在CPython解釋器中,在同一個(gè)進(jìn)程下開啟的多線程,同一時(shí)刻只能有一個(gè)線程執(zhí)行,無法利用多核優(yōu)勢(shì)
PS:我們平常所使用的python是C語(yǔ)言編寫的,所以大部分人所說的python也指CPython,CPython是python的官方版本,若是指其他語(yǔ)言寫的python,一般情況下會(huì)指明,如Jypthon、Pypy等
2、為什么會(huì)出現(xiàn)GIL
隨著電腦多核CPU的出現(xiàn),python為了充分利用多核CPU,進(jìn)行多線程的編程方式便普及了起來,但是隨之而來的困難是線程之間數(shù)據(jù)的一致性和狀態(tài)同步,python為了解決這個(gè)數(shù)據(jù)不能同步的問題,所以設(shè)計(jì)了GIL全局解釋器鎖,其實(shí)就是互斥鎖
說到互斥鎖,在多線程互斥鎖中共享全局變量的時(shí)候會(huì)有線程對(duì)全局變量進(jìn)行的資源競(jìng)爭(zhēng),會(huì)對(duì)全局變量的修改產(chǎn)生不是我們想要的結(jié)果,而那個(gè)時(shí)候用到的是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)
執(zhí)行結(jié)果:
99
在上面的例子里,我創(chuàng)建了10個(gè)線程來爭(zhēng)奪對(duì) n 進(jìn)行 -1 操作,但是結(jié)果并非我想要的,所以我在這里加入了互斥鎖
如下例(加線程互斥鎖):
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)
執(zhí)行結(jié)果:
90
這次就可以得到我想要的結(jié)果
3、GIL的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
保證數(shù)據(jù)的正確性
缺點(diǎn):
單個(gè)進(jìn)程下,開啟多個(gè)線程,犧牲了執(zhí)行效率,無法實(shí)現(xiàn)并行,只能實(shí)現(xiàn)并發(fā)
4、如何體現(xiàn)GIL全局解釋器鎖
在Cpython解釋器中,當(dāng)python代碼有一個(gè)線程開始訪問解釋器的時(shí)候,GIL會(huì)把這個(gè)大鎖給鎖上,此時(shí)此刻其他的線程只能干等著,無法對(duì)解釋器的資源進(jìn)行訪問,這一點(diǎn)就和互斥鎖相似。而只是這個(gè)過程發(fā)生在我們的Cpython中,同時(shí)也需要等這個(gè)線程分配的時(shí)間到了,這個(gè)線程把GIL釋放掉,類似互斥鎖的lock.release()一樣,另外其他的線程才開始跑起來。
以上就是Cpython解釋器中的GIL全局解釋器鎖的詳細(xì)內(nèi)容,更多關(guān)于GIL全局解釋器鎖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python獲取響應(yīng)某個(gè)字段值的3種實(shí)現(xiàn)方法
這篇文章主要介紹了python獲取響應(yīng)某個(gè)字段值的3種實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04使用Pycharm(Python工具)新建項(xiàng)目及創(chuàng)建Python文件的教程
這篇文章主要介紹了使用Pycharm(Python工具)新建項(xiàng)目及創(chuàng)建Python文件的教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04python+matplotlib實(shí)現(xiàn)禮盒柱狀圖實(shí)例代碼
這篇文章主要介紹了python+matplotlib實(shí)現(xiàn)禮盒柱狀圖實(shí)例代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01利用Django框架中select_related和prefetch_related函數(shù)對(duì)數(shù)據(jù)庫(kù)查詢優(yōu)化
這篇文章主要介紹了利用Python的Django框架中select_related和prefetch_related函數(shù)對(duì)數(shù)據(jù)庫(kù)查詢的優(yōu)化的一個(gè)實(shí)踐例子,展示如何在實(shí)際中利用這兩個(gè)函數(shù)減少對(duì)數(shù)據(jù)庫(kù)的查詢次數(shù),需要的朋友可以參考下2015-04-04python人工智能自定義求導(dǎo)tf_diffs詳解
這篇文章主要為大家介紹了python人工智能自定義求導(dǎo)tf_diffs詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07