




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第一文帶你深入探究Go語言中的sync.Map目錄1.Map的基本實(shí)現(xiàn)原理2.sync.Map的實(shí)現(xiàn)原理2.1sync.Map的結(jié)構(gòu)體定義2.2sync.Map的讀取實(shí)現(xiàn)2.3sync.Map的寫入實(shí)現(xiàn)2.4sync.Map的刪除實(shí)現(xiàn)2.5sync.Map的遍歷實(shí)現(xiàn)在Go語言中,有一個(gè)非常實(shí)用的并發(fā)安全的Map實(shí)現(xiàn):sync.Map,它是在Go1.9版本中引入的。相比于標(biāo)準(zhǔn)庫中的map,它的最大特點(diǎn)就是可以在并發(fā)情況下安全地讀寫,而不需要加鎖。在這篇博客中,我們將深入探討sync.Map的基本原理,幫助讀者更好地理解并使用這個(gè)并發(fā)安全的Map。
1.Map的基本實(shí)現(xiàn)原理
在介紹sync.Map的基本實(shí)現(xiàn)原理之前,我們需要先了解一下Go語言標(biāo)準(zhǔn)庫中的map實(shí)現(xiàn)原理。在Go中,map是基于哈希表實(shí)現(xiàn)的。當(dāng)我們向map中添加元素時(shí),它會(huì)根據(jù)key計(jì)算出一個(gè)哈希值,然后將這個(gè)值映射到一個(gè)桶中。如果該桶中已經(jīng)有了元素,它會(huì)遍歷桶中的元素,查找是否已經(jīng)存在相同的key,如果存在就更新對應(yīng)的值,否則就添加一個(gè)新的鍵值對。
下面是一個(gè)簡單的map示例:
m:=make(map[string]int)
m["a"]=1
m["b"]=2
fmt.Println(m["a"])//Output:1
當(dāng)我們運(yùn)行這段代碼時(shí),Go語言會(huì)自動(dòng)幫我們分配一個(gè)哈希表和若干個(gè)桶,然后將鍵值對添加到對應(yīng)的桶中。這樣,當(dāng)我們需要訪問某個(gè)key對應(yīng)的值時(shí),Go語言會(huì)根據(jù)哈希值快速定位到對應(yīng)的桶,然后遍歷桶中的元素,查找是否有相同的key,如果找到了就返回對應(yīng)的值。
2.sync.Map的實(shí)現(xiàn)原理
sync.Map是Go語言標(biāo)準(zhǔn)庫中的一個(gè)并發(fā)安全的Map實(shí)現(xiàn),它可以在并發(fā)情況下安全地讀寫,而不需要加鎖。那么,它是如何實(shí)現(xiàn)這種并發(fā)安全性的呢?下面我們就來一步步地解析sync.Map的實(shí)現(xiàn)原理。
2.1sync.Map的結(jié)構(gòu)體定義
首先,讓我們來看一下sync.Map的結(jié)構(gòu)體定義:
typeMapstruct{
musync.Mutex
readatomic.Value//readOnly
dirtymap[interface{}]interface{}
missesint
dirtyLockeduintptr
}
從上面的代碼中可以看出,sync.Map的實(shí)現(xiàn)主要是依賴于一個(gè)互斥鎖(sync.Mutex)和兩個(gè)map(read和dirty)。其中,read和dirty的作用分別是什么呢?我們先來看一下read的定義:
typereadOnlystruct{
mmap[interface{}]interface{}
amendedbool
}
可以看到,read只有一個(gè)成員m,它是一個(gè)map類型。而amended則表示read中的鍵值對是否被修改過。接下來,我們來看一下dirty的定義:
typedirtystruct{
mmap[interface{}]interface{}
dirtymap[interface{}]bool
missesint
}
和read不同的是,dirty中包含了兩個(gè)map:m和dirty。其中,m存儲(chǔ)了被修改過的鍵值對,而dirty則存儲(chǔ)了哪些鍵值對被修改過。
2.2sync.Map的讀取實(shí)現(xiàn)
在sync.Map中,讀取操作非常簡單,直接從readOnly中的m中查找即可。如果readOnly中的鍵值對被修改過,則需要從dirty中查找。讀取操作的實(shí)現(xiàn)代碼如下:
func(m*Map)Load(keyinterface{})(valueinterface{},okbool){
read,_:=m.read.Load().(readOnly)
value,ok=read.m[key]
if!okread.amended{
m.mu.Lock()
read,_=m.read.Load().(readOnly)
value,ok=read.m[key]
if!okread.amended{
value,ok=read.m[key]
m.mu.Unlock()
return
}
在這段代碼中,我們首先從readOnly中的m中查找鍵值對。如果鍵值對不存在且readOnly中的鍵值對被修改過,則需要獲取互斥鎖,并重新從readOnly中查找。如果還是沒有找到,那么就從dirty中查找。
2.3sync.Map的寫入實(shí)現(xiàn)
在sync.Map中,寫入操作需要分兩步完成。首先,我們需要判斷readOnly中的鍵值對是否被修改過,如果沒有被修改過,則直接將鍵值對添加到readOnly中的m中即可。否則,我們需要獲取互斥鎖,然后將鍵值對添加到dirty中的m中,并將對應(yīng)的鍵添加到dirty中的dirty中。寫入操作的實(shí)現(xiàn)代碼如下:
func(m*Map)Store(key,valueinterface{}){
read,_:=m.read.Load().(readOnly)
ifv,ok:=read.m[key];!ok!read.amended{
m.mu.Lock()
read,_=m.read.Load().(readOnly)
ifv,ok:=read.m[key];!ok{
read=readOnly{m:read.m,amended:true}
read.m[key]=value
m.read.Store(read)
m.mu.Unlock()
}else{
m.mu.Lock()
dirty:=m.dirtyLocked!=0
if!dirty{
m.dirtyLocked=1
m.dirty=make(map[interface{}]interface{})
m.dirty[key]=value
if!ok{
m.dirty[key]=value
m.dirty[key]=true
ifdirty{
m.mu.Unlock()
return
m.read.Store(readOnly{m:read.m,amended:true})
m.mu.Unlock()
}
在這段代碼中,我們首先從readOnly中的m中查找鍵值對。如果鍵值對不存在且readOnly中的鍵值對沒有被修改過,則需要獲取互斥鎖,并重新從readOnly中查找。如果還是沒有找到,則將鍵值對添加到readOnly中的m中,并將amended設(shè)置為true。否則,我們需要獲取互斥鎖,并將鍵值對添加到dirty中的m中,并將對應(yīng)的鍵添加到dirty中的dirty中。如果dirty中已經(jīng)存在該鍵,則只需要更新dirty中的鍵值即可。如果dirty中沒有該鍵,則需要在dirty中添加該鍵,并將該鍵的dirty置為true。
接下來,我們需要判斷dirty是否被鎖定。如果dirty被鎖定,則直接退出函數(shù)。否則,我們需要將readOnly中的amended設(shè)置為true,并將readOnly存儲(chǔ)回read中。
2.4sync.Map的刪除實(shí)現(xiàn)
在sync.Map中,刪除操作也需要分兩步完成。首先,我們需要判斷readOnly中的鍵值對是否被修改過,如果沒有被修改過,則直接從readOnly中的m中刪除鍵值對即可。否則,我們需要獲取互斥鎖,然后將鍵添加到dirty中的dirty中,并將dirty中的對應(yīng)鍵的值設(shè)置為false。刪除操作的實(shí)現(xiàn)代碼如下:
func(m*Map)Delete(keyinterface{}){
read,_:=m.read.Load().(readOnly)
if_,ok:=read.m[key];ok||read.amended{
m.mu.Lock()
read,_=m.read.Load().(readOnly)
if_,ok:=read.m[key];ok||read.amended{
ifm.dirty==nil{
m.dirty=make(map[interface{}]interface{})
m.dirty[key]=false
m.dirty[key]=true
m.read.Store(readOnly{m:read.m,amended:true})
m.mu.Unlock()
}
在這段代碼中,我們首先從readOnly中的m中查找鍵值對。如果鍵值對存在或者readOnly中的鍵值對被修改過,則需要獲取互斥鎖,并重新從readOnly中查找。如果還是沒有找到,則將鍵添加到dirty中的dirty中,并將dirty中的對應(yīng)鍵的值設(shè)置為false。接下來,我們需要判斷dirty是否為nil,如果為nil,則需要將dirty初始化為一個(gè)空map。然后,我們將鍵添加到dirty中,并將dirty中的對應(yīng)鍵的值設(shè)置為true。最后,我們將readOnly中的amended設(shè)置為true,并將readOnly存儲(chǔ)回read中。
2.5sync.Map的遍歷實(shí)現(xiàn)
在sync.Map中,遍歷操作需要將readOnly和dirty中的所有鍵值對進(jìn)行合并,并返回所有未被刪除的鍵值對。遍歷操作的實(shí)現(xiàn)代碼如下:
func(m*Map)Range(ffunc(key,valueinterface{})bool){
read,_:=m.read.Load().(readOnly)
ifread.amended{
m.mu.Lock()
read,_=m.read.Load().(readOnly)
ifread.amended{
read=readOnly{
m:merge(read.m,m.dirty),
read.amended=false
m.read.Store(read)
m.dirty=nil
m.mu.Unlock()
fork,v:=rangeread.m{
if!f(k,v){
break
funcmerge(m1,m2map[interface{}]interface{})map[interface{}]interface{}{
iflen(m1)==0len(m2)==0{
returnnil
iflen(m1)==0{
returnm2
iflen(m2)==0{
returnm1
m:=make(map[interface{}]interface{})
fork,v:=rangem1{
m[k]=v
fork,v:=rangem2{
if_,ok:=m[k];!ok||!v.(bool){
m[k]=v
returnm
}
在這段代碼中,我們首先從readOnly中獲取所有的鍵值對,并檢查是否有鍵值對被修改過。如果鍵值對被修改過,則需要獲取互斥鎖,并將readOnly和dirty中的鍵值對合并,然后將合并后的鍵值對存儲(chǔ)回readOnly中,并將dirty設(shè)置為nil。接下來,我們遍歷readOnly中的所有鍵值對,并調(diào)用f函數(shù)來處理鍵值對。如果f函數(shù)返回false,則遍歷過程結(jié)束
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 22025年護(hù)師考試?yán)碚撝改显囶}及答案
- 民用航空器維修工具使用方法試題及答案
- 消防安全工作中的創(chuàng)新思維試題及答案
- 無人機(jī)駕駛法律責(zé)任試題及答案解析
- 2025年建造師各科目復(fù)習(xí)的實(shí)踐經(jīng)驗(yàn)與總結(jié)分享試題及答案
- 四年級數(shù)學(xué)(四則混合運(yùn)算)計(jì)算題專項(xiàng)練習(xí)與答案匯編
- 初級審計(jì)案例題目試題及答案
- 深入分析審計(jì)報(bào)告的重要性與方法試題及答案
- 電能計(jì)量裝置技術(shù)要求與安裝規(guī)范-電能計(jì)量裝置的構(gòu)成及其附屬設(shè)備
- 總結(jié)與展望2025年中級會(huì)計(jì)試題及答案
- 在線網(wǎng)課知慧《數(shù)智時(shí)代的商業(yè)變革(山大(威海))》單元測試考核答案
- 中外比較文學(xué)研究專題智慧樹知到期末考試答案2024年
- CO2氣體保護(hù)焊-基本操作方法(焊接技能)
- (高清版)TDT 1012-2016 土地整治項(xiàng)目規(guī)劃設(shè)計(jì)規(guī)范
- 人工智能在水土保持中的應(yīng)用
- 鄉(xiāng)村振興中的鄉(xiāng)村安全與穩(wěn)定維護(hù)
- 營銷策劃 -菌小寶益生菌2023品牌介紹手冊
- 夫妻婚內(nèi)房產(chǎn)贈(zèng)與合同范本【專業(yè)版】
- 馬克思主義基本原理智慧樹知到課后章節(jié)答案2023年下湖南大學(xué)
- (完整版)數(shù)字信號處理教案(東南大學(xué))
- 第三章-綠色植物與生物圈的水循環(huán)-課件
評論
0/150
提交評論