亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在同一個圍棋例程中使用鎖和鎖

在同一個圍棋例程中使用鎖和鎖

Go
收到一只叮咚 2022-09-26 15:47:54
我正在Go中使用RWMutex進行實驗,我意識到通過以下代碼可以具有此行為:戈魯廷 1 - 洛克戈魯廷 1 - 倫洛克戈魯廷 2 - 洛克戈魯廷 2 - 倫洛克戈魯廷 2 - 鎖定戈魯廷2 - 解鎖戈魯廷 1 - 鎖戈魯廷 1 - 解鎖package mainimport (    "fmt"    "sync"    "time")type RLockAndLockStruct struct {    mu sync.RWMutex    mapEx map[string]string}func main() {    r := &RLockAndLockStruct{}    r.mapEx = make(map[string]string)    go r.RLockAndLockTest("test", "goroutine 1 - ")    go r.RLockAndLockTest("test", "goroutine 2 - ")    time.Sleep(4000 * time.Millisecond)}func (r *RLockAndLockStruct) RLockAndLockTest(value string, goroutine string) string {    r.mu.RLock()    fmt.Printf("%sRLock\n", goroutine)    t := r.mapEx[value]    r.mu.RUnlock()    fmt.Printf("%sRUnlock\n", goroutine)    if len(t) <= 0 {        time.Sleep(500 * time.Millisecond)        r.mu.Lock()        fmt.Printf("%sLock\n", goroutine)        r.mapEx[value] = value        r.mu.Unlock()        fmt.Printf("%sUnlock\n", goroutine)        return r.mapEx[value]    }    return t}我在一些文章中讀到,在戈魯廷斯中使用地圖的正確方法是使用RWMutex和RLock進行讀取和鎖定寫入。但是,正如您在上面的代碼中看到的,如果兩個 Goroutine 幾乎在同一時間啟動,則可能在同一映射中有兩個寫入,而不是一個寫入和一個讀取。由此,我在這里有一些問題:有沒有辦法保證在映射上只寫入一個 goroutine(輸入上面的 if 代碼塊)和所有其他使用新值讀取該映射的例程(避免輸入 if 代碼塊)?它是戈魯丁和地圖的正確實現嗎?
查看完整描述

1 回答

?
烙印99

TA貢獻1829條經驗 獲得超13個贊

這是因為您的代碼中有一個爭用條件。您讀鎖定地圖以讀取它,做出決定,然后寫鎖定它。不能保證當您獲得寫鎖定時,您做出決定的條件仍然有效。


正確的方法是在鎖定后重新測試條件:


    if len(t) <= 0 {

        time.Sleep(500 * time.Millisecond)

        r.mu.Lock()

        if len(r.mapEx[value])<=0 {

          fmt.Printf("%sLock\n", goroutine)

          r.mapEx[value] = value

        }

        r.mu.Unlock()

        return value

請注意上面的用法,否則它將不得不再次訪問地圖。return value


查看完整回答
反對 回復 2022-09-26
  • 1 回答
  • 0 關注
  • 111 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號