中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python編程中Python與GIL互斥鎖的關系

發布時間:2021-09-14 17:32:55 來源:億速云 閱讀:119 作者:chen 欄目:開發技術

這篇文章主要介紹“Python編程中Python與GIL互斥鎖的關系”,在日常操作中,相信很多人在Python編程中Python與GIL互斥鎖的關系問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Python編程中Python與GIL互斥鎖的關系”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

GIL 的起源

Python 第一次發布是在 1991 年,當時的 CPU 都是單核,單核中,多線程主要為了一邊做IO,一邊做 CPU 計算而設計的,Python 編譯器是由 C 語言編寫的,因此也叫 CPython,那時候很多編程語言沒有自動內存管理的功能,為了實現自動垃圾回收,Python 為每一個對象進行了引用計數,當引用計數為 0 的時候說明該對象可以回收,從而釋放內存了,比如:

>>> import sys
>>> data = { 'gzh': 'Python七號'}
>>> var1 = data
>>> sys.getrefcount(data)
3
>>>

這里 data 對象就有 3 個引用, 一個是本身,一個是變量 var1,一個是 getrefcount 函數的參數,如果此時又有一個線程引用了 data,那么引用計數再增加 1,如果某個線程使用了 data 后運行結束,那么引用計數就減少 1,多線程對同一個變量「引用計數」進行修改,就會遇到 race conditions(競爭),為了避免 race conditions,最簡單有效的辦法就是加一個互斥鎖。

如果對每一個對象都加鎖,有可能引發另一個問題,就是死鎖,而且頻繁的獲取和釋放會導致性能下降,最簡單有效的方法就是加一個解釋器鎖,線程在執行任何字節碼時都先獲取解釋器鎖,這就避免了死鎖,而且不會有太多的性能消耗。當時 CPU 都是單核,而且這種 GIL 設計簡單,并不會影響性能,因此一直沿用至今天。GIL 存在最主要的原因,就是因為 Python 的內存管理不是線程安全的,這就是 GIL 產生并存在的主要緣由。

嘗試消除 GIL

CPU 進入多核時代后,可以同時做多個計算任務, GIL 才真正變成問題。在 1999 年,有個叫 Greg Stein 的大佬基于 Python 1.5 版本消除了 GIL,取代代之的是在可變數據結構上加上更細粒度的鎖,也提交了補丁用于去除對全局可變對象的依賴,然后在標準測試時表明去除 GIL 后單線程比不去除時慢了近 2 倍,測試的機器還是當時性能最好 Windows 機器。也就是說除去了 GIL 后,你使用 2 個 CPU 才能獲取比原來 1 個 CPU 稍微好一點的性能,這種提升明顯得不償失,Greg Stein 的嘗試也就失敗告終。

Python 之父 Guido van Rossum 也歡迎社區的志愿者去嘗試去除 GIL,只要不降低單線程的性能,但他也提到,去掉 GIL 不是一件容易的事。

Python 開發者郵件列表中也偶爾會有去除 GIL 的議題,但是以下需求必須滿足:

  • 簡單。從長遠來看該方案必須是可實施、可維護的。

  • 并發。去除 GIL 必須能提升多線程的性能。

  • 速度。去除 GIL 不能降低單線程的性能。

  • 滿足 CPython 的特性。該方案必須支持 CPython 的功能,比如 __del__ 和弱引用。

  • API 的兼容性。該方案應與所有現有CPython擴展使用的宏在源方面兼容。

  • 及時銷毀不可達對象,回收內存。

  • 有序銷毀,比如不可達對象 X 引用了 A,那么應該在銷毀 A 之前先銷毀 X(有些垃圾回收算法并不能做到這一點)。

有些需求不容易被滿足,比如 4,5,7,目前,還沒有人滿足以上需求的同時去除 GIL 成功的。

積重難返

這些年 Python 實在太火了,很多優秀的庫都是基于 CPython 進行編寫的,很多都是 90 年代的 C 擴展庫,如果要除去 GIL,那么很多基于 GIL 編寫的 C 擴展便無法使用,也就是去了 GIL,Python 生態有很多擴展或三方庫者無法使用。

還有一個很明顯的例子,Python 解釋器不止有 CPython,還有用 Java 編寫的 Python,.NET 實現的 IronPython,這些解釋器完全沒有 GIL,可是有多少人為它們編寫擴展呢?

Python 之所以如此火爆,與它有著豐富的三方庫開箱即用有著很大的關系,積重難返,去除 GIL 很困難。

為什么 Python3 一開始時不去除 GIL

Python3 在最開始時是有機會實現很多新功能,在此過程中,打破了一些現有的 C 擴展,然后需要更新和移植更改以配合 Python 3,這也是 Python3 一開始不被社區所接受的原因。

與 Python2 相比,刪除 GIL 將使 Python3 在單線程性能方面更慢,而且很多優秀的擴展將不能再使用,如果真的這樣,可以想象 Python3 不可能有未來,最終的結果是 Python3 仍然保持有 GIL。

但 Python3 也為現有的 GIL 帶來了重大改進,在 Python 3.2 版本中,確保了計算密集型線程和 I/O 密集型線程并存時, I/O 密集型長期獲取不到 GIL 而無法執行的問題,提升了多線程的性能。

到此,關于“Python編程中Python與GIL互斥鎖的關系”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

古蔺县| 板桥市| 兴城市| 西乌珠穆沁旗| 莎车县| 政和县| 江达县| 阳朔县| 尤溪县| 容城县| 湘西| 洛川县| 东方市| 敦煌市| 平江县| 安新县| 商河县| 通道| 阿尔山市| 拉萨市| 建湖县| 永城市| 朝阳县| 吉林市| 颍上县| 涪陵区| 洪湖市| 若羌县| 巴里| 舒兰市| 宿松县| 正阳县| 成武县| 惠水县| 柳州市| 内乡县| 平遥县| 彰化县| 监利县| 前郭尔| 长垣县|