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

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

for 循環中的 Goroutines 返回不同的值

for 循環中的 Goroutines 返回不同的值

Go
桃花長相依 2022-05-23 16:39:10
我正在嘗試練習圍棋套路。我在這里想念什么?這段代碼給我返回了一個不同的數組結果。func goRoutinesSearch(body string, keywords []string) {     lowerBody := strings.ToLower(body)     var matched []string     var wg sync.WaitGroup     wg.Add(len(keywords))     for _, word := range keywords {         go func(w string) {             defer wg.Done()             if strings.Contains(lowerBody, w) {                 matched = append(matched, w)             }         }(word)     }     wg.Wait()     fmt.Print(matched)}
查看完整描述

1 回答

?
慕仙森

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

matched = append(matched, w)

是一個不同步的關鍵部分,導致競爭條件。這不是原子操作。goroutine 有許多不同的交錯,會導致不同的輸出,并且是完全不可預測的,可能會丟失數據。


使這個線程安全(并發執行安全)的最簡單方法是matched使用mutex同步訪問:


func goRoutinesSearch(body string, keywords []string) {

     lowerBody := strings.ToLower(body)

     var mutex = &sync.Mutex{}

     var matched []string

     var wg sync.WaitGroup

     wg.Add(len(keywords))

     for _, word := range keywords {

         go func(w string) {

             defer wg.Done()

             if strings.Contains(lowerBody, w) {

                 mutex.Lock()

                 matched = append(matched, w)

                 mutex.Unlock()

             }

         }(word)

     }

     wg.Wait()

     fmt.Print(matched)

}

互斥鎖確保在任何給定時間只有一個 go 例程能夠執行append,matched因此您永遠不會覆蓋附加。


我認為你可能仍然有不同的數組結果,具體取決于 goroutines 的執行順序,但你不會丟失數據,因為它是同步的。


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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