Go語言——sync.Map原始碼分析
點選這裡,檢視更具體原理,優化點,方法原始碼分析等更多重要內容
簡介: 眾所周知,go 普通的 map 是不支援併發的,換而言之,不是執行緒 (goroutine) 安全的。博主是從 golang 1.4 開始使用的,那時候 map 的併發讀是沒有支援,但是併發寫會出現髒資料。golang 1.6 之後,併發地讀寫會直接 panic:
fatal error: concurrent map read and map write
package main
func main() {
m := make(map[int]int)
go func() {
for {
_ = m[1]
}
}()
go func() {
for {
m[2] = 2
}
}()
select {}
}
所以需要支援對 map 的併發讀寫時候,博主使用兩種方法:
1、 第三方類庫 concurrent-map。
2、 map 加上 sync.RWMutex 來保障執行緒 (goroutine) 安全的。
golang 1.9 之後,go 在 sync 包下引入了併發安全的 map,也為博主提供了第三種方法。本文重點也在此,為了時效性,本文基於 golang 1.10 原始碼進行分析。
sync.Map
結構體
Map
type Map struct {
mu Mutex //互斥鎖,用於鎖定dirty map
read atomic.Value //優先讀map,支援原子操作,註釋中有readOnly不是說read是隻讀,而是它的結構體。read實際上有寫的操作
dirty map[interface{}]*entry // dirty是一個當前最新的map,允許讀寫
misses int // 主要記錄read讀取不到資料加鎖讀取read map以及dirty map的次數,當misses等於dirty的長度時,會將dirty複製到read
}
readOnly
readOnly 主要用於儲存,通過原子操作儲存在 Map.read 中元素。
type readOnly struct {
m map[interface{}]*entry
amended bool // 如果資料在dirty中但沒有在read中,該值為true,作為修改標識
}
entry
type entry struct {
// nil: 表示為被刪除,呼叫Delete()可以將read map中的元素置為nil
// expunged: 也是表示被刪除,但是該鍵只在read而沒有在dirty中,這種情況出現在將read複製到dirty中,即複製的過程會先將nil標記為expunged,然後不將其複製到dirty
// 其他: 表示存著真正的資料
p unsafe.Pointer // *interface{}
}
原理
關鍵字: Go 原始碼分析
更多原創文章乾貨分享,請關注公眾號
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- go sync.Map原始碼分析Go原始碼
- Go語言—sync.Cond原始碼分析Go原始碼
- sync.Map原始碼分析原始碼
- Go語言Context包原始碼學習GoContext原始碼
- Go 語言效能分析Go
- 深度解密 Go 語言之 sync.map解密Go
- Go語言的前景分析Go
- 【譯】Go 語言原始碼貢獻官方指導文件Go原始碼
- go rpc 原始碼分析GoRPC原始碼
- go ants原始碼分析Go原始碼
- Go 語言的詞法分析和語法分析(1)Go詞法分析語法分析
- 個人經驗分享如何閱讀Go語言原始碼Go原始碼
- 詳解Go語言排程迴圈原始碼實現Go原始碼
- Go語言————1、初識GO語言Go
- Go 1.9 sync.MapGo
- Go的WaitGroup原始碼分析GoAI原始碼
- 不得不知道的Golang之sync.Map原始碼分析Golang原始碼
- Go 語言實戰: 編寫可維護 Go 語言程式碼建議Go
- Fabric 1.0原始碼分析(4)Chaincode(鏈碼)#platforms(鏈碼語言平臺)原始碼AIPlatform
- k8s client-go原始碼分析 informer原始碼分析(6)-Indexer原始碼分析K8SclientGo原始碼ORMIndex
- k8s client-go原始碼分析 informer原始碼分析(4)-DeltaFIFO原始碼分析K8SclientGo原始碼ORM
- Uber Go 語言編碼規範Go
- [譯] Go 語言實戰: 編寫可維護 Go 語言程式碼建議Go
- GO語言————2、GO語言環境安裝Go
- k8s client-go原始碼分析 informer原始碼分析(5)-Controller&Processor原始碼分析K8SclientGo原始碼ORMController
- 以太坊原始碼分析(44)p2p-database.go原始碼分析原始碼DatabaseGo
- 以太坊原始碼分析(45)p2p-dial.go原始碼分析原始碼Go
- 以太坊原始碼分析(46)p2p-peer.go原始碼分析原始碼Go
- 以太坊原始碼分析(48)p2p-server.go原始碼分析原始碼ServerGo
- 以太坊原始碼分析(49)p2p-table.go原始碼分析原始碼Go
- 以太坊原始碼分析(50)p2p-udp.go原始碼分析原始碼UDPGo
- Go 語言專案程式碼品質Go
- 使用Go語言製作二維碼Go
- Go 語言如何解決程式碼耦合Go
- k8s client-go原始碼分析 informer原始碼分析(1)-概要分析K8SclientGo原始碼ORM
- Go 語言核心知識(一)--- 環境變數和原始碼檔案Go變數原始碼
- Go 語言的詞法分析和語法分析(2)—Import宣告的解析Go詞法分析語法分析Import
- 【Go語言入門系列】(八)Go語言是不是面嚮物件語言?Go物件