1. 程式人生 > >python的GIL鎖的是什麼

python的GIL鎖的是什麼

有幾個結論:
1、python的執行緒是原生執行緒,由作業系統排程
2、python的多執行緒環境下,每執行完100條指令後(稱為“軟時鐘”)會觸發一次“python級執行緒排程”,所謂的“python級執行緒排程”,指的是執行緒A釋放GIL,執行緒B獲得GIL,從而掌握了對直譯器的“執行大權”。GIL實際上是再普通不過的執行緒鎖,獲得、釋放GIL就是加解鎖操作,像win32下是WaitForSingleObject和SetEvent,而solaris下則是mutex_lock和mutex_unlock。所以,“python級執行緒排程”本質上是GIL的鎖爭用,從某種意義上也可以說GIL鎖被順帶用作“python級執行緒排程”。
3、GIL保護的是直譯器,由於Python C-API是直譯器的一部分,它也能保護Python C-API,但不能保護使用者資料。所謂的“保護直譯器”,是指GIL可避免直譯器在多執行緒下破壞python物件的簿記資訊,如引用計數。舉個例子,執行緒A和B共享一個python物件,該物件不管是系統級物件還是使用者級物件,其引用計數的修改和記憶體的回收都是由直譯器自動完成的,寫成偽碼如下:
```
--obj->ref_cnt  [1]
if(obj->ref_cnt) free(obj) [2]
```
有多執行緒程式設計經驗的人一眼就能看出,只有[1]和[2]組成一個原子操作,才可保證多執行緒下引用計數操作的正確性。按鎖粒度最小化的原則,我們只需用一把鎖保護住[1]和[2]即可,這把鎖是細粒度鎖。但python不這麼做,它直接使用GIL這樣的粗粒度鎖,造成多執行緒序列執行上述偽碼,自然也能保證安全。
由於GIL是一個粗粒度鎖,在多核多執行緒下的效率自然不如細粒度鎖,但作為指令碼語言,單執行緒也是python的重要場景,而且單執行緒下像GIL這樣的粗粒度鎖是比較容易控制和優化掉的(事實上,單執行緒下GIL壓根就不建立),反而像細粒度鎖不太好優化。所以,歷史上有人曾做過去除GIL的版本,其在單執行緒的基準測試中的表現反而不如GIL版本。