Go語言sync.Mutex包源碼解讀

互斥鎖sync.Mutex是在并發程序中對共享資源進行訪問控制的主要手段,對此Go語言提供了非常簡單易用的機制。sync.Mutex為結構體類型,對外暴露Lock()、Unlock()、TryLock()三種方法,分別用于阻塞加鎖、解鎖、非阻塞加鎖操作(加鎖失敗后快速返回結果不會陷入阻塞狀態)。

sync.Mutex內部實現比較復雜,但是堅持閱讀之后,卻有很大的收益。比如如何設計一個任務調度系統,每個時間點只有一個任務執行,在調度任務時,既需要保證任務執行的效率也需要保證一個任務不會出現餓死的情況,sync.Mutex的內部機制可能會給你一些借鑒經驗。除此之外,還能夠讓你對TryLock有更加深刻的理解和在使用Mutex時的注意點。

版本:go1.24.1

數據結構

//package: pakcage:src\internal\sync\mutex.gotype Mutex struct {state int32sema  uint32
}const (mutexLocked = 1 << iota // mutex is lockedmutexWokenmutexStarvingmutexWaiterShift = iotastarvationThresholdNs = 1e6
)

Mutex結構比較簡單,定義了兩個字段:

  • state:根據bit位的劃分,表示多種含義。
  • sema:信號量,用于管理協程阻塞和喚醒的關鍵機制,確保協程高效調度和喚醒。

state字段通過分割比特位來表示三種狀態和記錄當前等待獲取鎖的協程數量,從低位到高位依次為:

  • mutexLocked:1bit位,當前mutex是否被鎖定,0表示未鎖定,1表示鎖定。
  • mutexWoken:1bit位,當前是否有協程從阻塞中被喚醒,0表示未被喚醒,1表示有協程被喚醒。
  • mutexStarving:1bit位,當前mutex的所處模式,0表示正常模式,1表示饑餓模式。
  • ?mutexWaiterShift:位偏移量,利用偏移后的位來記錄等待協程的數量,占用29bit位。

兩種模式

正常模式和饑餓模式是sync.mutex包的精髓,通過這兩種模式來保證性能和公平。

  • 正常模式:追求性能,允許新的協程通過自旋和競爭來快速獲取鎖,減少協程的上下文切換開銷。
  • 饑餓模式:兜底公平性,確保等待者不被餓死。

在正常模式下,等待者按FIFO順序排隊,但被喚醒的等待者不擁有mutex,并與新到達的goroutines競爭所有權。而新加入的goroutines有一個優勢——它們已經在CPU上運行,并且可能有很多,所以喚醒的等待者很有可能會失敗。在這種情況下,它被排在等待隊列的前面。如果等待者獲得mutex的時間超過1ms,將mutex將切換到饑餓模式。

在饑餓模式下,mutex的所有權直接從正在解鎖的goroutine移交(hand off)給隊列前面的等待者。新到達的goroutines不會嘗試獲取mutex,即使mutex已經解鎖,(新到達的goroutines)也不會嘗試自旋。相反,它們把自己排在等待隊列的尾部。如果一個等待者獲得了mutex的所有權,并且發現以下任一條件:(1)它是隊列中最后一個等待者;(2)它等待的時間少于1毫秒;那么mutex將切換回正常工作模式。

源碼解讀

請訪問github倉庫,以注釋的方式進行解讀,提高閱讀體驗和保證思考的連續性。

倉庫地址:wuqiong818/go-source-interpretation: go語言解讀

參考文章

Go1.24.1源碼

Go專家編程 sync.Mutex章節

【Go萬字洗髓經】Golang中sync.Mutex的單機鎖:實現原理與底層源碼-CSDN博客

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

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

相關文章

SQL注入流量分析

免責聲明&#xff1a;本文僅作分享 ~ 目錄 SQL注入流量分析 特征&#xff1a; sqlmap注入類型 漏洞環境搭建 error_sql: bool_sql: time_sql: union_sql: Stacked Queries: Inline Queries: SQL注入流量分析 https://www.freebuf.com/column/161797.html SQLMAP攻擊…

Linux 時間同步工具 Chrony 簡介與使用

一、Chrony 是什么&#xff1f; chrony 是一個開源的網絡時間同步工具&#xff0c;主要由兩個組件組成&#xff1a; chronyd&#xff1a;后臺服務進程&#xff0c;負責與時間服務器交互&#xff0c;同步系統時鐘。chronyc&#xff1a;命令行工具&#xff0c;用于手動查看或修…

Flutter:Flutter SDK版本控制,fvm安裝使用

1、首先已經安裝了Dart&#xff0c;cmd中執行 dart pub global activate fvm2、windows配置系統環境變量 fvm --version3、查看本地已安裝的 Flutter 版本 fvm releases4、驗證當前使用的 Flutter 版本&#xff1a; fvm flutter --version5、切換到特定版本的 Flutter fvm use …

Vue 項目中的package.json各部分的作用和用法的詳細說明

1. 基本信息 {"name": "my-vue-app","version": "1.0.0","description": "A Vue.js project","author": "Your Name <your.emailexample.com>","license": "MIT"…

Linux網絡編程——TCP通信的四次揮手

一、前言 上篇文章講到了TCP通信建立連接的“三次握手”的一些細節&#xff0c;本文再對TCP通信斷開連接的“四次揮手”的過程做一些分析了解。 二、TCP斷開連接的“四次揮手” 我們知道TCP在建立連接的時需要“三次握手”&#xff0c;三次握手完后就可以進行通信了。而在通…

某碰瓷國賽美賽,號稱第三賽事的數模競賽

首先我非常不能理解的就是怎么好意思自稱第三賽事的呢&#xff1f;下面我們進行一個簡單討論&#xff0c;當然這里不對國賽和美賽進行討論。首先我們來明確一點&#xff0c;比賽的含金量由什么來定&#xff1f;這個可能大家的評價指標可能不唯一&#xff0c;我通過DeepSeek選取…

Redis 緩存問題:緩存雪崩、緩存擊穿、緩存穿透

文章目錄 緩存雪崩緩存擊穿緩存穿透在實際的業務場景中,Redis 通常作為緩存和其他數據庫(例如 MySQL)搭配使用,用來減輕數據庫的壓力。但是在使用 Redis 作為緩存數據庫的過程中,可能會遇到一些常見問題,例如緩存穿透、緩存擊穿和緩存雪崩等。 緩存雪崩 緩存雪崩是指緩存…

Qt 入門 4 之標準對話框

Qt 入門 4 之標準對話框 Qt提供了一些常用的對話框類型,它們全部繼承自QDialog類,并增加了自己的特色功能,比如獲取顏色、顯示特定信息等。下面簡單講解這些對話框,可以在幫助索引中查看Standard Dialogs關鍵字,也可以直接索引相關類的類名。 本文將以一個新的項目為主介紹不…

買不起了,iPhone 或漲價 40% ?

周知的原因&#xff0c;新關稅對 iPhone 的打擊&#xff0c;可以說非常嚴重。 根據 Rosenblatt Securities分析師的預測&#xff0c;若蘋果完全把成本轉移給消費者。 iPhone 16 標配版的價格&#xff0c;可能上漲43%。 iPhone 16 標配的價格是799美元&#xff0c;上漲43%&am…

軟件需求分析習題匯編

需求工程練習題 一、選擇題 1. 軟件需求規格說明書的內容不應包括對&#xff08; &#xff09;的描述。 A. 主要功能B. 算法的詳細過程C. 用戶界面及運行環境D. 軟件的性能 *正確答案:*B:算法的詳細過程; 2. 需求分析最終結果是產生&#xff08; &#xff09; A. 項目開發…

clickhouse注入手法總結

clickhouse 遇到一題clickhouse注入相關的&#xff0c;沒有見過&#xff0c;于是來學習clickhouse的使用&#xff0c;并總結相關注入手法。 環境搭建 直接在docker運行 docker pull clickhouse/clickhouse-server docker run -d --name some-clickhouse-server --ulimit n…

智能語音識別工具開發手記

智能語音識別工具開發手記 序言&#xff1a;聽見數字化的聲音 在縣級融媒體中心的日常工作中&#xff0c;我們每天需要處理大量音頻素材——從田間地頭的采訪錄音到演播室的節目原聲&#xff0c;從緊急會議記錄到專題報道素材。二十多年前&#xff0c;筆者剛入職時&#xff0…

TDengine 3.3.6.0 版本中非常實用的 Cols 函數

簡介 在剛剛發布的 TDengine 3.3.6.0 版本 中&#xff0c;新增了一個非常實用的 函數COLS &#xff0c;此函數用于獲取選擇函數所在行列信息&#xff0c;主要應用在生成報表數據&#xff0c;每行需要出現多個選擇函數結果&#xff0c;如統計每天最大及最小電壓&#xff0c;并報…

【AI學習】AI Agent(人工智能體)

1&#xff0c;AI agent 1&#xff09;定義 是一種能夠感知環境、基于所感知到的信息進行推理和決策&#xff0c;并通過執行相應動作來影響環境、進而實現特定目標的智能實體。 它整合了多種人工智能技術&#xff0c;具備自主學習、自主行動以及與外界交互的能力&#xff0c;旨…

【MCP】VSCode Cline配置MongoDB連接

VSCode MCP插件配置MongoDB連接教程 前言 本文將介紹如何在VSCode中配置Cline插件連接MongoDB。 環境準備 VSCodeNode.jsMongoDB服務器Cline插件 配置步驟 1. 安裝MCP插件 在VSCode擴展商店中搜索"Cline"并安裝。 安裝完之后需要配置API平臺以及設置API-KEY。…

this指針 和 類的繼承

一、this指針 Human類的屬性fishc與Human&#xff08;&#xff09;構造器的參數fishc同名&#xff0c;但卻是兩個東西。使用this指針讓構造器知道哪個是參數&#xff0c;哪個是屬性。 this指針&#xff1a;指向當前的類生成的對象 this -> fishc fishc當前對象&#xff08;…

使用PyTorch訓練VGG11模型:Fashion-MNIST圖像分類實戰

本文將通過代碼實戰&#xff0c;詳細講解如何使用 PyTorch 和 VGG11 模型在 Fashion-MNIST 數據集上進行圖像分類任務。代碼包含數據預處理、模型定義、訓練與評估全流程&#xff0c;并附上訓練結果的可視化圖表。所有代碼可直接復現&#xff0c;適合深度學習初學者和進階開發者…

汽車BMS技術分享及其HIL測試方案

一、BMS技術簡介 在全球碳中和目標的戰略驅動下&#xff0c;新能源汽車產業正以指數級速度重塑交通出行格局。動力電池作為電動汽車的"心臟"&#xff0c;其性能與安全性不僅直接決定了車輛的續航里程、使用壽命等關鍵指標&#xff0c;更深刻影響著消費者對電動汽車的…

打造船岸“5G+AI”智能慧眼 智驅力賦能客船數智管理

項目介紹 船舶在航行、作業過程中有著嚴格的規范要求&#xff0c;但在實際航行與作業中往往會因為人為的疏忽&#xff0c;發生事故&#xff0c;導致人員重大傷亡和財產損失&#xff1b; 為推動安全治理模式向事前預防轉型&#xff0c;實現不安全狀態和行為智能預警&#xff0c…

C#二叉樹

C#二叉樹 二叉樹是一種常見的數據結構&#xff0c;它是由節點組成的一種樹形結構&#xff0c;其中每個節點最多有兩個子節點。二叉樹的一個節點通常包含三部分&#xff1a;存儲數據的變量、指向左子節點的指針和指向右子節點的指針。二叉樹可以用于多種算法和操作&#xff0c;…