python中的GIL-全局解釋器鎖

轉載:
https://www.cnblogs.com/zipxzf/p/11621630.html

使用場景:

採用多進程還是多線程的方式(多核CPU)要看實際應用場景是:
(1)多I/O操作
(2)密集計算(循環等操作)
如果是多IO,單核多線程效率更高
如果是密集計算,使用多進程

臨界資源

因爲多個線程可以共享進程的內存空間,因此要實現多個線程間的通信相對簡單,大家能想到的最直接的辦法就是設置一個全局變量,多個線程共享這個全局變量即可。但是當多個線程共享同一個變量(我們通常稱之爲“資源”)的時候,很有可能產生不可控的結果從而導致程序失效甚至崩潰。如果一個資源被多個線程競爭使用,那麼我們通常稱之爲“臨界資源”,對“臨界資源”的訪問需要加上保護,否則資源會處於“混亂”的狀態。

上鎖

我們可以通過“鎖”來保護“臨界資源”,只有獲得“鎖”的線程才能訪問“臨界資源”,而其他沒有得到“鎖”的線程只能被阻塞起來,直到獲得“鎖”的線程釋放了“鎖”,其他線程纔有機會獲得“鎖”,進而訪問被保護的“臨界資源”。

GIL鎖

13 比較遺憾的一件事情是Python的多線程並不能發揮CPU的多核特性,這一點只要啓動幾個執行死循環的線程就可以得到證實了。之所以如此,是因爲Python的解釋器有一個“全局解釋器鎖”(GIL)的東西,任何線程執行前必須先獲得GIL鎖,然後每執行100條字節碼,解釋器就自動釋放GIL鎖,讓別的線程有機會執行,這是一個歷史遺留問題,但是即便如此,就如我們之前舉的例子,使用多線程在提升執行效率和改善用戶體驗方面仍然是有積極意義的。

單線程+異步I/O

現代操作系統對I/O操作的改進中最爲重要的就是支持異步I/O。如果充分利用操作系統提供的異步I/O支持,就可以用單進程單線程模型來執行多任務,這種全新的模型稱爲事件驅動模型。Nginx就是支持異步I/O的Web服務器,它在單核CPU上採用單進程模型就可以高效地支持多任務在多核CPU上,可以運行多個進程(數量與CPU核心數相同),充分利用多核CPU。用Node.js開發的服務器端程序也使用了這種工作模式,這也是當下實現多任務編程的一種趨勢。

在Python語言中**,單線程+異步I/O的編程模型稱爲協程**,有了協程的支持,就可以基於事件驅動編寫高效的多任務程序。協程最大的優勢就是極高的執行效率,因爲子程序切換不是線程切換,而是由程序自身控制,因此,沒有線程切換的開銷。協程的第二個優勢就是不需要多線程的鎖機制,因爲只有一個線程,也不存在同時寫變量衝突,在協程中控制共享資源不用加鎖,只需要判斷狀態就好了,所以執行效率比多線程高很多。如果想要充分利用CPU的多核特性,最簡單的方法是多進程+協程,既充分利用多核,又充分發揮協程的高效率,可獲得極高的性能。關於這方面的內容,我稍後會做一個專題來進行講解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章