电竞比分网-中国电竞赛事及体育赛事平台

分享

golang map 讀寫鎖與深度拷貝的坑

 飲茶仙人 2020-02-10

0X01

golang中,map(字典)無(wú)法并發(fā)讀寫

簡(jiǎn)單來(lái)說(shuō),新建萬(wàn)條線程對(duì)同一個(gè)map又讀又寫,會(huì)報(bào)錯(cuò)。

為此,最好加鎖,其實(shí)性能影響并不明顯。

type taskCache struct{
    sync.RWMutex
    data map[string] interface{}
}

 

 

0X02

golang中,map(字典)為引用拷貝。

a = 字典一

b = a 

實(shí)際上是直接將指針傳給了b。

 

于是,有一個(gè)讀取,寫的時(shí)候直接讀map并返回

復(fù)制代碼
func GetAllTasks() (result map[string]interface{}, err error) {
    // 獲得當(dāng)前的所有任務(wù)
    DEMO.RLock()
    defer DEMO.RUnlock()
    return DEMO.data, err
}
復(fù)制代碼

而在線程中

// 接收后直接打印
fmt.Println(store.GetAllTasks())

結(jié)果居然報(bào)錯(cuò),map讀寫沖突。

 

于是,我返回去一遍一遍看代碼,覺(jué)得自己的讀寫鎖寫錯(cuò)了。

調(diào)式折騰了半天,最后發(fā)現(xiàn),在接收后不用 fmt.Println 打印就不會(huì)報(bào)錯(cuò)。

這很不科學(xué),然后在接收打印前后加上讀鎖,不報(bào)錯(cuò)了。

 

0X03

所以golang,加了讀寫鎖的時(shí)候,要返回全部值,還不能直接返回這個(gè)字典,因?yàn)橹苯臃祷剡@個(gè)字典,返回了指針,操作的時(shí)候要不還要加讀寫鎖,要不就報(bào)錯(cuò)。

還沒(méi)有直接的取地址的值重新給另一個(gè)變量的東西,自己寫個(gè)遍歷,一個(gè)一個(gè)賦值吧,蛋疼,坑貨,坑了一晚上

var cache = make(map[string]interface{})
for k,v := range Demo.data{
    cache[k] = v
}

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多