哈嘍大家好,我是鹹魚 幾天前有媒體報道稱,經過多次辯論,Python 指導委員會打算批准通過 PEP 703 提案,**讓 GIL(全局解釋器)鎖在 CPython 中成為一個可選項** PEP 703 提案主要目標是使 GIL 變成可選項,即允許 Python 解釋器在特定情況下不使用GIL ![ ...
哈嘍大家好,我是鹹魚
幾天前有媒體報道稱,經過多次辯論,Python 指導委員會打算批准通過 PEP 703 提案,讓 GIL(全局解釋器)鎖在 CPython 中成為一個可選項
PEP 703 提案主要目標是使 GIL 變成可選項,即允許 Python 解釋器在特定情況下不使用GIL
這將允許 Python 在多核處理器上更好地利用並行性,從而提高多線程程式的性能
PEP 703 提案建議新增一個配置項 --disable-gil
,加了這個選項之後就可以關閉 GIL 鎖,如果想要開啟 GIL 鎖,把 --disable-gil
去掉即可
關於 PEP 703 提案的具體內容有興趣的小伙伴們可以去看一下
PEP 703 提案:https://peps.python.org/pep-0703/
接下來我們來看下外媒的這篇報道吧!
原文:https://www.infoworld.com/article/3704248/python-moves-to-remove-the-gil-and-boost-concurrency.html
譯文如下:
經過多次辯論,Python 指導委員會打算批准 PEP 703 提案——”使全局解釋器鎖在 CPython 中可選“
PEP 703 提案是多年來嘗試移除 Python GIL 鎖的最終結果。GIL 鎖的移除消除了多線程的主要障礙,使得 Python 成為真正的多核語言,並且顯著提高其並行工作負載的性能
有了 PEP 703 提案,Python 中對多線程和併發的一流支持離成為現實又近了一步
為什麼要移除 GIL ?
在 python 中,其記憶體管理系統通過維護每個對象的引用數量來跟蹤對象的使用情況(Python 的引用計數機制)
當對象的引用計數減少為 0 時,系統就會刪除該對象
由於 Python 誕生於多處理器系統很少見且多核處理器還未出現的時代,所以這種引用計數機制不是線程安全的
相反,Python 通過一次只允許一個線程訪問對象來實現線程安全,這便是 GIL 的目的
這些年來許多項目都嘗試移除 GIL,它們確實能夠使多線程程式運行地更快,但代價是降低了單線程程式的性能
鑒於絕大多數 Python 應用程式都是單線程,所以這是一個糟糕的權衡。儘管對 GIL 的改進提升了 Pyhton 對多線程應用程式的處理,但仍舊是一個嚴重的瓶頸
Python 的核心開發人員最終決定從 CPython 中移除 GIL,但前提是它可以在不減慢單線程程式速度的情況下完成
沒了 GIL,Python 該如何運行?
當前關於 Python 的無 GIL 版本的提案都提到了使用多種技術來使引用計數線程安全,並且維持單線程程式的速度不變或者僅對其產生最小的影響
下麵是一些關於無 GIL 版本的提案:
- Biased reference counting(帶偏見的引用計數)
單個線程訪問的對象的引用計數與多個線程訪問的對象的引用計數處理方式不同(單線程的更快一點)
由於大多數對象只被一個線程訪問,因此對單線程程式的影響被降到最低
- Immortalization(永生)
某些對象(如 None
)永遠不會被回收,因此不需要跟蹤它們的引用計數
- Thread-safe memory allocation(線程安全的記憶體分配)
一個新的 CPython 對象記憶體分配系統將使垃圾收集器中的對象跟蹤更容易,並以線程安全的方式分配記憶體
- Deferred reference counting(延遲引用計數)
某些對象(如模塊中的頂級函數)的引用計數可以安全地延遲。這樣可以節省時間和資源
- A revised garbage collector(修改後的垃圾收集器)
CPyhton 垃圾收集器清楚迴圈對象的引用(比如兩個或多個對象互相引用)
無 GIL構建對垃圾收集器做了許多更改,例如刪除用於跟蹤對象的“生成”系統
如何逐步引入無 GIL 的 Python?
實施 PEP 703 是一個長期項目,將會在幾年內分成多個階段進行。在此期間,CPython 解釋器先過渡到使 no-GIL 版本可選,然後是支持,最後成為標準
為了實現這個目標,CPython 的開發者將會為 CPython 添加一個實驗性的 ’no-GIL‘ 構建模式,以便大家可以在有或沒有 GIL 的情況下編譯 CPython 的版本
最終,no-GIL 構建將成為預設值
下麵則是相關的計劃:
1、no-GIL 是可選項
對於 CPython 開發人員和 Python 社區來說,no-GIL CPython 的第一個版本將是實驗性
這個實驗階段有幾個目標:
- 首先讓 Python 社區的其他成員參與進來。對 Python 的任何重大更改都需要更廣泛的Python 社區的支持。實驗性版本為 Python 用戶提供了一種安全地試驗測試其代碼的方法,並且能夠觀察非線程和線程代碼的行為方式
- 其次讓 Python 發行版可以選擇(而不是”要求“)提供 no-GIL 的 Python。像 Conda 或WinPython 這樣的 Python 發行版需要保證與原有的 CPython 相容。在過渡階段,安裝的時候可以提供常規或者 no-GIL 版本的 CPython 選項,這將允許 Conda 或WinPython 用戶選擇最適合他們需求的版本
- 最後確定 no-GIL 項目是否值得。如果社區大規模嘗試 no-GIL 的構建後對結果不滿意,CPython 核心開發人員保留退出的權利。雙重構建意味著在短期內會增加維護負擔,但如果 no-GIL 項目被證明不值得,他們也有退路
2、支持 no-GIL Python
下一階段將提供 no-GIL 構建作為 CPython 支持的替代構建
用戶可以選擇安裝 no-GIL 或 GIL 版本,其中任何一個版本都是正式支持的 CPython 版本,可以接收錯誤修複、安全補丁和更新
這個階段的一大目標是設置一個期限,使 no-GIL 成為預設值
這可能與其他 Python 功能的棄用和刪除在同一時間線上發生——至少兩三個版本,也意味著至少兩到三年
3、no-GIL 成為預設
最後階段是將 CPython 的 no-GIL 版本作為預設版本,並從 CPython 中刪除所有與 GIL 相關的代碼
”我們不想等待太久“,CPython 核心開發人員 Thomas Wouters 寫道,“因為擁有兩種通用的構建模式可能會給社區帶來沉重的負擔(例如,它可以將測試資源和調試場景加倍),但我們也不能急於求成。我們認為可能需要長達五年的時間才能達到這個階段
移除 GIL 的最大挑戰
儘管技術挑戰令人生畏,但這項計劃的最大挑戰不僅僅是技術挑戰。更大的問題是如何使 Python 生態系統的其餘部分與這些變化保持一致且確保 no-GIL 的 Python 不會產生比它解決的問題更多的問題
根據 Wouters 的說法,”...適應非 GIL 構建所需的第三方代碼的任何更改都應該只適用於 GIL 構建(儘管仍然需要解決與舊 Python 版本的向後相容性問題)“
如上所述,另一個重大挑戰是”帶領Python社區的其他成員,” Wouters 說,“……確保我們想要做出的改變,以及我們希望他們做出的改變,是可以接受的
“在我們承諾完全切換到 no-GIL 構建之前,我們需要看到社區對它的支持,” Wouters說。“我們不能只是改變預設值,然後期望社區找出他們需要做些什麼來支持它”
Python 社區在從 Python 2 過渡到 Python 3 的過程中經歷了巨大的成長痛苦,因此任何像移除 GIL 這樣的重大更改都必須完全向後相容
正如 Wouters 所說,“我們不希望再出現 Python 3 的情況。”
不過在危險和挑戰之外,還有一個巨大的回報——Python 最終支持了程式員在 21 世紀所期望的並行性