Python GIL(全局解釋器鎖)機制對多線程性能影響的深度分析

在Python開發領域,GIL(Global Interpreter Lock)一直是一個廣受關注的技術話題。在3.13已經默認將GIL去除,在詳細介紹3.13的更親前,我們先要留了解GIL的技術本質、其對Python程序性能的影響。本文將主要基于CPython(用C語言實現的Python解釋器,也是目前應用最廣泛的Python解釋器)展開討論。

GIL的技術定義

GIL(Global Interpreter Lock)是CPython解釋器中的一個互斥鎖(mutex)機制,其核心作用是保護Python對象的訪問,防止多個本地線程同時執行Python字節碼。從技術實現角度來看,GIL確保在任一時刻只有一個線程能在Python解釋器中執行代碼。

在實際運行過程中,假設程序創建了10個并發線程,在任一時刻檢查CPU核心時,只能觀察到一個線程在執行。每個線程在執行特定數量的字節碼操作后,都會釋放GIL并退出當前核心。在CPython的默認實現中,每個線程可以在釋放GIL之前執行100個字節碼指令。GIL釋放后,其他等待線程中的一個將獲得鎖并開始執行。

從實現機制來看,GIL可以被視為一個線程執行令牌,線程必須獲取這個令牌才能執行字節碼指令。

GIL的技術必要性

GIL的存在與CPython的內存管理機制密切相關。要理解GIL的必要性,需要先了解CPython的內存管理實現原理。

CPython采用引用計數(reference counting)作為其主要的內存管理機制。系統會為每個Python對象維護一個引用計數器,記錄指向該對象的引用數量。當引用計數降至零時,對象占用的內存將被立即釋放。

在多線程環境下對同一Python對象的訪問在多線程場景下,考慮如下情況:假設有3個線程同時持有對同一Python對象的引用,此時該對象的引用計數為3。當一個線程釋放對該對象的引用時,計數值降為2。

這里存在一個關鍵的技術問題:如果兩個線程同時釋放對該對象的引用,會出現競爭條件(race condition)。在這種情況下,引用計數可能只會減少一次而不是預期的兩次,導致最終引用計數為2而不是1。這將導致對象永遠保持非零引用計數,使得垃圾回收器無法回收該對象,最終造成內存泄漏。

GIL的設計正是為了解決這個問題。通過確保同一時刻只有一個線程在執行,GIL有效防止了多線程環境下的引用計數競爭問題。這種機制保證了對Python對象的訪問是串行的,從而維護了解釋器內部狀態的一致性。

GIL的技術局限性

GIL雖然解決了內存管理的并發問題,但同時也帶來了性能方面的技術挑戰。

最主要的性能開銷來自于線程執行時頻繁的GIL獲取和釋放操作。這種額外的同步開銷導致了多線程程序在某些場景下的性能反而低于單線程程序。

以下是具體的性能測試示例。首先是單線程實現:

 importtime  defmyfunc():  """  執行5億次迭代的高精度計時測試"""  before_time=time.perf_counter()  for_inrange(500000000):  pass  after_time=time.perf_counter()  elapsed_time=after_time-before_time  print(f"Time taken in total: {elapsed_time:.6f} seconds")  if__name__=="__main__":  myfunc()

單線程執行結果顯示耗時約8.426秒

對比使用兩個線程的實現:

 importtime  importthreading  defworker(iterations, thread_id):  """  執行指定迭代次數的工作線程函數參數: iterations (int): 迭代執行次數thread_id (int): 線程標識號"""  print(f"Thread {thread_id} starting.")  for_inrange(iterations):  pass  print(f"Thread {thread_id} finished.")  defmyfunc():  """  將5億次迭代平均分配給兩個線程執行的性能測試"""  total_iterations=500000000  half_iterations=total_iterations//2  thread1=threading.Thread(target=worker, args=(half_iterations, 1))  thread2=threading.Thread(target=worker, args=(half_iterations, 2))  print("Starting threads...")  before_time=time.perf_counter()  thread1.start()  thread2.start()  thread1.join()  thread2.join()  after_time=time.perf_counter()  elapsed_time=after_time-before_time  print(f"Time taken in total: {elapsed_time:.6f} seconds")  if__name__=="__main__":  myfunc()

多線程執行結果顯示耗時約11.256秒

這個性能測試清晰地展示了GIL對Python多線程執行效率的影響,同時也說明了Python在實現真正的線程級并行計算時所面臨的技術限制。

3.13 前的技術解決方案

針對GIL帶來的限制,目前有多種技術解決方案,但每種方案都有其特定的應用場景和局限性:

多進程方案: 通過Python的

multiprocessing

模塊,可以創建多個獨立的Python解釋器進程,每個進程都擁有獨立的GIL和內存空間,從而實現真正的并行計算。

異步編程: 對于I/O密集型應用,可以使用異步編程模型(如asyncio)實現并發,這種方式可以在單線程環境下高效處理并發任務,降低GIL的影響。

替代性Python實現: 一些Python的其他實現(如Jython、IronPython、PyPy)采用了不同的內存管理機制,不依賴GIL。這些實現通過不同的技術方案避免了GIL的限制,但可能會帶來其他方面的權衡。

總結

GIL是CPython實現中的一個核心設計決策,它在保證內存管理安全性的同時也帶來了并行計算效率的限制。在實際開發中,需要根據具體的應用場景選擇合適的技術方案來規避或降低GIL的影響。理解GIL的技術本質和局限性,對于設計高性能的Python應用系統具有重要意義。

PEP 703 提出的移除 GIL 的設計,不僅解決了 GIL 帶來的多線程性能瓶頸,還通過細粒度鎖、樂觀鎖、RCU 和 STW 等多種機制,在性能和線程安全之間實現了巧妙的平衡。但是根據 Python 路線圖顯示,至少要到 2028 年,GIL 才會被默認禁用。所以目前來看的話了解GIL還是十分有必要的。

https://avoid.overfit.cn/post/3545a1aabf5a4452861804a1c5340ac0

作者:Sambhu Nampoothiri G

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67568.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67568.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67568.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從0開始使用面對對象C語言搭建一個基于OLED的圖形顯示框架(繪圖設備封裝)

目錄 圖像層的底層抽象——繪圖設備抽象 如何抽象一個繪圖設備? 橋接繪圖設備,特化為OLED設備 題外話:設備的屬性,與設計一個相似函數化簡的通用辦法 使用函數指針來操作設備 總結一下 圖像層的底層抽象——繪圖設備抽象 在…

Git 版本控制:基礎介紹與常用操作

目錄 Git 的基本概念 Git 安裝與配置 Git 常用命令與操作 1. 初始化本地倉庫 2. 版本控制工作流程 3. 分支管理 4. 解決沖突 5. 回退和撤銷 6. 查看提交日志 前言 在軟件開發過程中,開發者常常需要在現有程序的基礎上進行修改和擴展。但如果不加以管理&am…

(筆記+作業)書生大模型實戰營春節卷王班---L0G2000 Python 基礎知識

學員闖關手冊:https://aicarrier.feishu.cn/wiki/QtJnweAW1iFl8LkoMKGcsUS9nld 課程視頻:https://www.bilibili.com/video/BV13U1VYmEUr/ 課程文檔:https://github.com/InternLM/Tutorial/tree/camp4/docs/L0/Python 關卡作業:htt…

仿真設計|基于51單片機的高速路口貨車稱重系統仿真

目錄 具體實現功能 設計介紹 51單片機簡介 資料內容 仿真實現(protues8.7) 程序(Keil5) 全部內容 資料獲取 具體實現功能 (1)LCD1602液晶第一行顯示當前的車輛重量,第二行顯示車輛重量…

Ubuntu Server 安裝 XFCE4桌面

Ubuntu Server沒有桌面環境,一些軟件有桌面環境使用起來才更加方便,所以我嘗試安裝桌面環境。常用的桌面環境有:GNOME、KDE Plasma、XFCE4等。這里我選擇安裝XFCE4桌面環境,主要因為它是一個極輕量級的桌面環境,適合內…

2025:影刀RPA使用新實踐--CSDN博客下載

文章目錄 一鍵CSDN博客下載器程序說明指導說明使用步驟 獲取方法 一鍵CSDN博客下載器 程序說明 配置信息:CSDN賬號(手機號/郵箱/用戶名)、密碼、博客文件類型支持markdown格式、html格式(默認值markdown格式)、博客保…

深度學習的應用

目錄 一、機器視覺 1.1 應用場景 1.2 常見的計算機視覺任務 1.2.1 圖像分類 1.2.2 目標檢測 1.2.3 圖像分割 二、自然語言處理 三、推薦系統 3.1 常用的推薦系統算法實現方案 四、圖像分類實驗補充 4.1 CIFAR-100 數據集實驗 實驗代碼 4.2 CIFAR-10 實驗代碼 深…

前端js高級25.1.30

原型:函數的組成結構 通過這個圖我們需要知道。 假設我們創建了一個Foo函數。 規則:Function.protoType是函數顯示原型。__proto__是隱式對象。 Function、Object、Foo函數的__proto__指向了Function.protoType說明。這三個都依托function函數來創建。…

android 音視頻系列引導

音視頻這塊的知識點自己工作中有用到,一直沒有好好做一個總結,原因有客觀和主觀的。 客觀是工作太忙,沒有成段時間做總結。 主觀自己懶。 趁著這次主動離職拿了n1的錢,休息一下,對自己的人生做一下總結,…

為AI聊天工具添加一個知識系統 之80 詳細設計之21 符號邏輯 之1

本文要點 要點 前面我們討論了本項目中的正則表達式。現在我們將前面討論的正則表達式視為狹義的符號文本及其符號規則rule(認識的原則--認識上認識對象的約束),進而在更廣泛的視角下將其視為符號邏輯及其符號原則principle(知識…

.NET Core緩存

目錄 緩存的概念 客戶端響應緩存 cache-control 服務器端響應緩存 內存緩存(In-memory cache) 用法 GetOrCreateAsync 緩存過期時間策略 緩存的過期時間 解決方法: 兩種過期時間策略: 絕對過期時間 滑動過期時間 兩…

自動駕駛---蘇箐對智駕產品的思考

1 前言 對于更高級別的自動駕駛,很多人都有不同的思考,方案也好,產品也罷。最近在圈內一位知名的自動駕駛專家蘇箐發表了他自己對于自動駕駛未來的思考。 蘇箐是地平線的副總裁兼首席架構師,同時也是高階智能駕駛解決方案SuperDri…

Sklearn 中的邏輯回歸

邏輯回歸的數學模型 基本模型 邏輯回歸主要用于處理二分類問題。二分類問題對于模型的輸出包含 0 和 1,是一個不連續的值。分類問題的結果一般不能由線性函數求出。這里就需要一個特別的函數來求解,這里引入一個新的函數 Sigmoid 函數,也成…

FPGA|使用quartus II通過AS下載POF固件

1、將開發板設置到AS下載擋位,或者把下載線插入到AS端口 2、打開quartus II,選擇Tools→Programmer→ Mode選擇Active Serial Programming 3、點擊左側Add file…,選擇 .pof 文件 →start 4、勾選program和verify(可選&#xff0…

.Net / C# 分析文件編碼 并將 各種編碼格式 轉為 另一個編碼格式 ( 比如: GB2312→UTF-8, UTF-8→GB2312)

相關庫 .Net 8 編碼識別: github.com/CharsetDetector/UTF-unknown <PackageReference Include"UTF.Unknown" Version"2.5.1" />代碼 using UtfUnknown;var dir_path "D:\\Desktop\\新建文件夾2\\新建文件夾"; var dir_new_path &quo…

32. C 語言 安全函數( _s 尾綴)

本章目錄 前言什么是安全函數&#xff1f;安全函數的特點主要的安全函數1. 字符串操作安全函數2. 格式化輸出安全函數3. 內存操作安全函數4. 其他常用安全函數 安全函數實例示例 1&#xff1a;strcpy_s 和 strcat_s示例 2&#xff1a;memcpy_s示例 3&#xff1a;strtok_s 總結 …

淺談網絡 | 容器網絡之Flannel

目錄 云原生網絡架構深度解構&#xff1a;Flannel的設計哲學與實現機制Flannel架構解析&#xff1a;三層核心設計原則UDP模式&#xff08;用戶態隧道&#xff09;VXLAN模式&#xff08;內核態隧道&#xff09;Host-GW模式&#xff08;直連路由&#xff09; 生產環境架構選型與調…

autosar bsw 的關鍵模塊

AUTOSAR&#xff08;AUTomotive Open System ARchitecture&#xff09;的**基礎軟件層&#xff08;BSW&#xff0c;Basic Software&#xff09;**是汽車電子系統標準化的核心&#xff0c;負責提供硬件抽象、通信、診斷、安全等基礎服務。以下是BSW的關鍵模塊及其功能分類&#…

hive:基本數據類型,關于表和列語法

基本數據類型 Hive 的數據類型分為基本數據類型和復雜數據類型 加粗的是常用數據類型 BOOLEAN出現ture和false外的其他值會變成NULL值 沒有number,decimal類似number 如果輸入的數據不符合數據類型, 映射時會變成NULL, 但是數據本身并沒有被修改 創建表 創建表的本質其實就是在…

2025創業思路和方向有哪些?

創業思路和方向是決定創業成功與否的關鍵因素。以下是一些基于找到的參考內容的創業思路和方向&#xff0c;旨在激發創業靈感&#xff1a; 一、技術創新與融合&#xff1a; 1、智能手機與云電視結合&#xff1a;開發集成智能手機功能的云電視&#xff0c;提供通訊、娛樂一體化體…