天天看點

【Python程式設計學記】04 Python進階文法v3.1 | Part 01 GIL鎖 與 深、淺拷貝

今天學習的是GIL(全局解釋器鎖)、深拷貝與淺拷貝,平時敲代碼的時候沒有特别注意,有針對性的學習一下。

一般是面試題中有這些點,但在Python程式設計學習過程中,也是會涉及到的,是以幹脆就一并再過一遍。

GIL(全局解釋器鎖)

【Python程式設計學記】04 Python進階文法v3.1 | Part 01 GIL鎖 與 深、淺拷貝

在Ubuntu系統中使用 top指令/htop指令,可以檢視目前程序。(為了能夠學習到!特意去安裝下好了Ubuntu+虛拟機~也配置好了,誇我!)這裡想推薦一個部落客的安裝教程,非常詳細,手把手教學,參考部分步驟快速完成了安裝。

【Python程式設計學記】04 Python進階文法v3.1 | Part 01 GIL鎖 與 深、淺拷貝

 使用指令可以看到目前運作的一些程序,特意把虛拟機的辨別一起截進來。這裡和後面的截圖不一樣的原因是,後面的使用的老師截圖,使用的指令是 htop,可以清單顯示,顯示效果更佳。

為了說明線程間的調用,老師使用了兩個例子來講述,GIL鎖是如何對線程造成影響的。

先看代碼,導入線程包後,定義一個test函數,函數體死循環。

【Python程式設計學記】04 Python進階文法v3.1 | Part 01 GIL鎖 與 深、淺拷貝

為了更好檢視運作代碼的狀态,老師開了兩個視窗去實時檢視記憶體情況。左下淺灰就是上方代碼框,右邊是新開的程序檢視框。 

【Python程式設計學記】04 Python進階文法v3.1 | Part 01 GIL鎖 與 深、淺拷貝

 在另一個界面運作代碼,并切換到該頁面檢視程序記憶體狀态。可以發現兩個都占用了将近一半。也可以通過下方的python程序中看到,确實是python編譯在活動。

【Python程式設計學記】04 Python進階文法v3.1 | Part 01 GIL鎖 與 深、淺拷貝

為了說明Python程式代碼編譯的過程,老師畫了一張圖,從程式到機器運作,中間需要經過解釋器。而這也是Python被認為是解釋性程式設計語言的原因。Python解釋器有多種,這裡舉了常見的兩種例子,而我們預設的則是C語言編寫的cpython解釋器。

【Python程式設計學記】04 Python進階文法v3.1 | Part 01 GIL鎖 與 深、淺拷貝

講到這裡,老師提到,GIL是cpython解釋器在運作python程式代碼中處理多線程問題的遺留問題,jpython解釋器中沒有。而經過官方緻力去解決後,仍難以根除。綜合多種解決方案後,選擇了保留。

并且,這裡給出上面問題的參考答案。 

【Python程式設計學記】04 Python進階文法v3.1 | Part 01 GIL鎖 與 深、淺拷貝

讓我用聽完課的了解來說一遍,同時也再貼一遍問題:

【Python程式設計學記】04 Python進階文法v3.1 | Part 01 GIL鎖 與 深、淺拷貝
  • 首先什麼是GIL呢?也就是全局解釋器鎖,Global Interpretive Lock ,它是存在于使用Cpython解釋器對python代碼進行處理的時候一種現象。
  • 保證了python的單線程,因為每個線程執行前擷取到這個狀态,獨占解釋器!
  • 什麼時候釋放呢?不一定是線程結束,有的讀寫較久,為了避免引起阻塞,會解開一會兒,給别的線程用一下,等到線程恢複還是要使用GIL的。
  • 有個Python 2.X 和 3.X的差別,前者使用tickets計數(了解成計數器),門檻值為100,後者用計時器,門檻值到釋放鎖。
  • 多線程是否比單線程性能有提升呢?當然有,我們可以了解成多線程的話,異步發送請求,在發送請求過程中,耗費的時間其實已經得到節省了。
  • 為了簡便,可以了解IO阻塞的情況下,切換了其他線程去運作。

這裡老師的兩個問題我沒有涉及到,也就是IO阻塞,這個涉及到作業系統的知識,希望複習後能夠搞清楚相關的知識,并串起來,第二個是多線程可利用多核資源,也涉及到OS的知識。可以連到一起記憶。

如何解決GIL的問題呢?老師進行了補充,使用C語言編寫了一段:

【Python程式設計學記】04 Python進階文法v3.1 | Part 01 GIL鎖 與 深、淺拷貝

總的來說,提出兩個折衷方案:

  1. 第一個避免使用cpython解釋器,例如使用jpython替代;
  2. 需要多線程的話,可以使用其他程式設計語言實作,再用動态加載的方式列入。

深拷貝淺拷貝

忽然發現這部分截圖沒有,先放着。課聽完了,晚點補上截圖和筆記。

還是一句老話~刻意練習,每日精進。

繼續閱讀