我們要知道為什麽,更要知道為什麽。於是有了下面的深入研究:
首先強調壹下背景:
1,GIL是什麽?
GIL的全稱是全局解釋器鎖(Global Interpreter Lock),來源於python設計之初的考慮和為了數據安全而做出的決定。
2.每個CPU同壹時間只能執行壹個線程(其實單核CPU下的多線程只是並發,不是並行。並發性和並行性是同時處理多個請求的宏觀概念。但是並發和並行是有區別的。平行意味著兩個或更多的事件同時發生。並發意味著兩個或更多的事件發生在同壹時間間隔內。)
在Python多線程下,每個線程的執行模式是:
1,得到GIL
2.執行代碼,直到睡眠或python虛擬機掛起它。
3.釋放GIL
可見,壹個線程想要執行,必須先得到GIL,我們可以把GIL看作是壹個“通行證”,而在壹個python進程中,只有壹個GIL。不能獲得通過的線程不允許進入CPU執行。
在Python2.x中,GIL的釋放邏輯是當前線程遇到IO操作或者ticks計數達到100(ticks可以看作Python本身的壹個計數器,專門用於GIL,每次釋放後歸零,這個計數可以通過sys.setcheckinterval進行調整)。
但是,每次釋放GIL鎖時,線程都會爭奪鎖並切換線程,這會消耗資源。而且由於GIL鎖的存在,python中壹個進程同壹時間只能執行壹個線程(得到GIL的線程只能執行),這也是python多線程效率在多核CPU上不高的原因。
那麽python的多線程是不是完全沒用了?
這裏我們討論分類:
1,CPU密集型代碼(各種循環處理,計數等。),這種情況下由於大量的計算工作,滴答數很快就會達到閾值,然後觸發GIL的釋放和重新競爭(當然多線程之間來回切換是需要資源的),所以python中有很多。