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

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

是否有可能與 golang chan 存在競爭條件?

是否有可能與 golang chan 存在競爭條件?

Go
12345678_0001 2023-02-21 15:51:16
我的目標是創建一個簡單的 websocket 服務器。我使用 chan 來分發消息,例如通過調用<-messageChan. 有messageChan許多作家和讀者。但是,這個StackOverflow 問題讓我害怕導致無意中的死鎖。我做了什么:創建一個基本上做的測試:chan int用 0 到 1000填充 a 。創建 100 個 goroutine 來調用<-chan并將其添加到map[int]bool.t.Fatal如果不是 1000,則調用。len(map[int]bool)換句話說,競爭條件。然而,測試并沒有失敗??峙?,我做錯了什么,chan可能會陷入僵局。代碼main_test.gopackage mainimport (    "log"    "sync"    "testing")type MapMux struct {    sync.RWMutex    m map[int]bool    sync.WaitGroup}func (mux *MapMux) AddInt(i int) {    mux.RLock()    if _, isExist := mux.m[i]; isExist {        log.Fatal("race condition")    }    mux.RUnlock()    mux.Lock()    mux.m[i] = true    mux.Unlock()    mux.Done()}func TestChanRaceCondition(t *testing.T) {    l := 1000    c := make(chan int, l)    defer close(c)    for i := 0; i < l; i++ {        c <- i    }    mux := MapMux{sync.RWMutex{}, map[int]bool{}, sync.WaitGroup{}}    mux.Add(l)    for i := 0; i < 100; i++ {        go func(key int) {            for {                payload := <-c                log.Printf("go%d: %d", key, payload)                mux.AddInt(payload)            }        }(i)    }    mux.Wait()    if len(mux.m) != l {        t.Fatal("expected len:", l, ", actual len:", len(mux.m))    }}編輯:該代碼在該map[int]bool字段中查找重復項。編輯:這是因為defer close(c)。我應該檢查通道是否為每個操作打開。無論如何,這就是我學到的。希望這對新的 Golangers 有所幫助。學習到教訓了:一個頻道有很多作者和很多讀者是可以的。總是檢查val, isOpen := <-chan。如果isOpen== false,則停止使用該頻道。sync.RWMutex.RLock()不保證其他 goroutine 對地圖進行更改。所以,當心。這是應該做的。 func (mux *MapMux) AddInt(i int) {     mux.RLock()     if _, isExist := mux.m[i]; isExist {         log.Fatal("race condition")     }     mux.RUnlock()     mux.Lock()     if _, isExist := mux.m[i]; isExist {         log.Fatal("race condition")     }     mux.m[i] = true     mux.Unlock()     mux.Done() }
查看完整描述

1 回答

?
MMMHUHU

TA貢獻1834條經驗 獲得超8個贊

如果您在 goroutine 之間共享內存,就會發生數據競爭。如果你不在 goroutine 之間共享內存,你擔心的那種數據競爭就不會發生??赡苓€有其他競爭條件,例如您的AddInt方法中的競爭條件。正確的版本應該是:


func (mux *MapMux) AddInt(i int) {

    mux.RLock()

    if _, isExist := mux.m[i]; isExist {

        log.Fatal("race condition")

    }

    mux.RUnlock()

    mux.Lock()

    if _, isExist := mux.m[i]; isExist {

        log.Fatal("race condition")

    }

    mux.m[i] = true

    mux.Unlock()

    mux.Done()

}

這是因為無法保證另一個 goroutine 會更改 RUnlock 和 Lock 之間的映射。


在您的示例中,您正在 goroutine 之間共享一個映射。這意味著您必須使用互斥體來保護對它的所有訪問。如果你這樣做,就不會圍繞該地圖的使用進行數據競爭。


然而,一般來說,如果你能避免共享內存,你的程序就不會出現這樣的數據競爭。


查看完整回答
反對 回復 2023-02-21
  • 1 回答
  • 0 關注
  • 126 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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