我的目標是創建一個簡單的 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() }
是否有可能與 golang chan 存在競爭條件?
12345678_0001
2023-02-21 15:51:16
