主頁 > 知識庫 > 詳解Python中的GIL(全局解釋器鎖)詳解及解決GIL的幾種方案

詳解Python中的GIL(全局解釋器鎖)詳解及解決GIL的幾種方案

熱門標(biāo)簽:天津塘沽區(qū)地圖標(biāo)注 地圖標(biāo)注可以遠程操作嗎 滴滴地圖標(biāo)注公司 如何申請400電話代理 甘肅高頻外呼系統(tǒng) 400電話在線如何申請 智能電話機器人調(diào)研 江門智能電話機器人 杭州房產(chǎn)地圖標(biāo)注

先看一道GIL面試題:

描述Python GIL的概念, 以及它對python多線程的影響?編寫一個多線程抓取網(wǎng)頁的程序,并闡明多線程抓取程序是否可比單線程性能有提升,并解釋原因。

GIL:又叫全局解釋器鎖,每個線程在執(zhí)行的過程中都需要先獲取GIL,保證同一時刻只有一個線程在運行,目的是解決多線程同時競爭程序中的全局變量而出現(xiàn)的線程安全問題。它并不是python語言的特性,僅僅是由于歷史的原因在CPython解釋器中難以移除,因為python語言運行環(huán)境大部分默認(rèn)在CPython解釋器中。

通過一個案例了解單線程和多線程的cpu占用率:

打開Ubuntu終端命令:輸入htop,回車,紅色箭頭指向的2代表此時我的虛擬機中CPU有兩個核心數(shù)

下面通過一個案例了解單線程死循環(huán)和多線程死循環(huán)的CPU占用率:

單線程死循環(huán).py: 

#coding=utf-8
while True:
  pass

運行該程序,出現(xiàn)以下界面:

此時新開一個窗口,輸入htop,查看CPU占用率,其中一個CPU占用率幾乎為100%:

兩個線程死循環(huán).py

#coding=utf-8
import threading
 
#子線程死循環(huán)
def test():
  while True:
    pass
 
t1=threading.Thread(target=test)
t1.start()
 
#主線程死循環(huán),
while True:
  pass

此時新開一個終端,輸入htop查看CPU占用率,可以看到兩個CPU任何一個并沒有全部占滿,而是交替執(zhí)行的:

 這也就驗證了多線程下每個線程在執(zhí)行的過程中都需要先獲取GIL,保證同一時刻只有一個線程在運行。

由于GIL的存在,即使是多線程,事實上同一時刻只能保證一個線程在運行,既然這樣多線程的運行效率不就和單線程一樣了嗎,那為什么還要使用多線程呢?

由于以前的電腦基本都是單核CPU,多線程和單線程幾乎看不出差別,可是由于計算機的迅速發(fā)展,現(xiàn)在的電腦幾乎都是多核CPU了,最少也是兩個核心數(shù)的,這時差別就出來了:通過之前的案例我們已經(jīng)知道,即使在多核CPU中,多線程同一時刻也只有一個線程在運行,這樣不僅不能利用多核CPU的優(yōu)勢,反而由于每個線程在多個CPU上是交替執(zhí)行的,導(dǎo)致在不同CPU上切換時造成資源的浪費,反而會更慢。即原因是一個進程只存在一把gil鎖,當(dāng)在執(zhí)行多個線程時,內(nèi)部會爭搶gil鎖,這會造成當(dāng)某一個線程沒有搶到鎖的時候會讓cpu等待,進而不能合理利用多核cpu資源。

例如在使用多線程抓取網(wǎng)頁內(nèi)容時,遇到IO阻塞時,正在執(zhí)行的線程會暫時釋放GIL鎖,這時其它線程會利用這個空隙時間,執(zhí)行自己的代碼,因此多線程抓取比單線程抓取性能要好。

說到在這里要先介紹兩個概念:計算密集型和IO密集型

計算密集型:要進行大量的數(shù)值計算,例如進行上億的數(shù)字計算、計算圓周率、對視頻進行高清解碼等等。這種計算密集型任務(wù)雖然也可以用多任務(wù)完成,但是花費的主要時間在任務(wù)切換的時間,此時CPU執(zhí)行任務(wù)的效率比較低。

IO密集型:涉及到網(wǎng)絡(luò)請求(time.sleep())、磁盤IO的任務(wù)都是IO密集型任務(wù),這類任務(wù)的特點是CPU消耗很少,任務(wù)的大部分時間都在等待IO操作完成(因為IO的速度遠遠低于CPU和內(nèi)存的速度)。對于IO密集型任務(wù),任務(wù)越多,CPU效率越高,但也有一個限度。

解決GIL問題的方案:

1.使用其它語言,例如C,Java

2.使用其它解釋器,如java的解釋器jython

3.使用多進程

線程釋放GIL鎖的情況:

1.在IO操作等可能會引起阻塞的system call之前,可以暫時釋放GIL,但在執(zhí)行完畢后,必須重新獲取GIL。

2.Python 3.x使用計時器(執(zhí)行時間達到閾值后,當(dāng)前線程釋放GIL)或Python 2.x,tickets計數(shù)達到100。

GIL面試題參考答案:

  • Python語言和GIL沒有什么關(guān)系。僅僅是由于歷史原因在Cpython虛擬機(解釋器),難以移除GIL。
  • GIL:全局解釋器鎖。每個線程在執(zhí)行的過程都需要先獲取GIL,保證同一時刻只有一個線程可以執(zhí)行代碼。
  • 線程釋放GIL鎖的情況: 在IO操作等可能會引起阻塞的system call之前,可以暫時釋放GIL,但在執(zhí)行完畢后,必須重新獲取GIL Python 3.x使用計時器(執(zhí)行時間達到閾值后,當(dāng)前線程釋放GIL)或Python 2.x,tickets計數(shù)達到100。
  • Python使用多進程是可以利用多核的CPU資源的。
  • 多線程爬取比單線程性能有提升,因為遇到IO阻塞會自動釋放GIL鎖。

到此這篇關(guān)于詳解Python中的GIL(全局解釋器鎖)詳解及解決GIL的幾種方案的文章就介紹到這了,更多相關(guān)Python GIL全局解釋器鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Cpython解釋器中的GIL全局解釋器鎖
  • Python Threading 線程/互斥鎖/死鎖/GIL鎖
  • 簡要講解Python編程中線程的創(chuàng)建與鎖的使用
  • Python編程中Python與GIL互斥鎖關(guān)系作用分析

標(biāo)簽:臨汾 長春 漢中 德宏 重慶 東莞 廊坊 河池

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解Python中的GIL(全局解釋器鎖)詳解及解決GIL的幾種方案》,本文關(guān)鍵詞  詳解,Python,中的,GIL,全局,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《詳解Python中的GIL(全局解釋器鎖)詳解及解決GIL的幾種方案》相關(guān)的同類信息!
  • 本頁收集關(guān)于詳解Python中的GIL(全局解釋器鎖)詳解及解決GIL的幾種方案的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章